@kumologica/sdk 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (540) hide show
  1. package/README.md +1 -0
  2. package/bin/kl.js +3 -0
  3. package/cli/cli.js +6 -0
  4. package/cli/commands/build-commands/aws.js +49 -0
  5. package/cli/commands/build-commands/azure.js +43 -0
  6. package/cli/commands/build-commands/kumohub.js +7 -0
  7. package/cli/commands/build.js +6 -0
  8. package/cli/commands/create.js +32 -0
  9. package/cli/commands/deploy-commands/kumohub.js +114 -0
  10. package/cli/commands/deploy.js +6 -0
  11. package/cli/commands/doc-commands/html.js +61 -0
  12. package/cli/commands/doc.js +6 -0
  13. package/cli/commands/export-commands/cloudformation.js +338 -0
  14. package/cli/commands/export-commands/serverless.js +164 -0
  15. package/cli/commands/export-commands/terraform-commands/aws.js +193 -0
  16. package/cli/commands/export-commands/terraform-commands/azure.js +148 -0
  17. package/cli/commands/export-commands/terraform.js +6 -0
  18. package/cli/commands/export-commands/utils/validator.js +152 -0
  19. package/cli/commands/export.js +6 -0
  20. package/cli/commands/import-commands/mulesoft.js +61 -0
  21. package/cli/commands/import.js +6 -0
  22. package/cli/commands/open.js +46 -0
  23. package/cli/commands/test-utils/TestSuiteController.js +359 -0
  24. package/cli/commands/test-utils/TestSuiteController.test.js +171 -0
  25. package/cli/commands/test-utils/fixtures/example3-flow.json +148 -0
  26. package/cli/commands/test-utils/fixtures/package.json +6 -0
  27. package/cli/commands/test-utils/fixtures/s3-event.js +43 -0
  28. package/cli/commands/test-utils/util/output.js +14 -0
  29. package/cli/commands/test-utils/util/updates/index.js +17 -0
  30. package/cli/commands/test-utils/util/updates/pkg.js +13 -0
  31. package/cli/commands/test-utils/util/updates/templates/default-settings.js +209 -0
  32. package/cli/commands/test.js +66 -0
  33. package/cli/commands/utils.js +14 -0
  34. package/package.json +158 -0
  35. package/src/app/lib/aws/aws-profile.js +43 -0
  36. package/src/app/lib/aws/ca-alexa-api.js +29 -0
  37. package/src/app/lib/aws/ca-apigw-api.js +216 -0
  38. package/src/app/lib/aws/ca-cloudwatch-api.js +78 -0
  39. package/src/app/lib/aws/ca-codecommit-api.js +63 -0
  40. package/src/app/lib/aws/ca-dynamodb-api.js +27 -0
  41. package/src/app/lib/aws/ca-elb-api.js +44 -0
  42. package/src/app/lib/aws/ca-events-api.js +27 -0
  43. package/src/app/lib/aws/ca-iot-api.js +105 -0
  44. package/src/app/lib/aws/ca-s3-api.js +115 -0
  45. package/src/app/lib/aws/ca-sns-api.js +38 -0
  46. package/src/app/lib/aws/ca-sqs-api.js +51 -0
  47. package/src/app/lib/aws/cf.js +439 -0
  48. package/src/app/lib/aws/index.js +970 -0
  49. package/src/app/lib/aws/kl-iam-api.js +27 -0
  50. package/src/app/lib/aws/kl-rekognition-api.js +66 -0
  51. package/src/app/lib/aws/kl-ssm-api.js +24 -0
  52. package/src/app/lib/azure/index.js +80 -0
  53. package/src/app/lib/dependencies.js +50 -0
  54. package/src/app/lib/kumohub/index.js +201 -0
  55. package/src/app/lib/runtime-loader/index.js +42 -0
  56. package/src/app/lib/serverless/index.js +318 -0
  57. package/src/app/lib/stores/aws-cloud-config-store.js +35 -0
  58. package/src/app/lib/stores/azure-config-store.js +24 -0
  59. package/src/app/lib/stores/kumohub-config-store.js +24 -0
  60. package/src/app/lib/stores/project-info-config-store.js +26 -0
  61. package/src/app/lib/stores/settings-cloud-store.js +117 -0
  62. package/src/app/lib/stores/settings-cloud-store.spec.js +26 -0
  63. package/src/app/lib/stores/settings-network-store.js +119 -0
  64. package/src/app/lib/stores/settings-network-store.spec.js +27 -0
  65. package/src/app/lib/stores/store.js +97 -0
  66. package/src/app/lib/stores/test-config-store.js +26 -0
  67. package/src/app/lib/stores/user-preference-store.js +44 -0
  68. package/src/app/lib/utils/editor.js +98 -0
  69. package/src/app/lib/utils/fix-path.js +15 -0
  70. package/src/app/main-process/favicon.ico +0 -0
  71. package/src/app/main-process/main-window.js +209 -0
  72. package/src/app/main-process/menu.js +219 -0
  73. package/src/app/main-process/modal-home.js +118 -0
  74. package/src/app/main-process/modal-newproject.js +119 -0
  75. package/src/app/main-process/modal-nodelibrary.js +90 -0
  76. package/src/app/main-process/modal-welcome.js +114 -0
  77. package/src/app/main-process/runtime-manager.js +141 -0
  78. package/src/app/main.js +590 -0
  79. package/src/app/preload.js +633 -0
  80. package/src/app/ui/editor-api/lib/admin/context.js +42 -0
  81. package/src/app/ui/editor-api/lib/admin/flow.js +55 -0
  82. package/src/app/ui/editor-api/lib/admin/flows.js +53 -0
  83. package/src/app/ui/editor-api/lib/admin/index.js +155 -0
  84. package/src/app/ui/editor-api/lib/admin/nodes.js +164 -0
  85. package/src/app/ui/editor-api/lib/auth/clients.js +17 -0
  86. package/src/app/ui/editor-api/lib/auth/index.js +267 -0
  87. package/src/app/ui/editor-api/lib/auth/permissions.js +51 -0
  88. package/src/app/ui/editor-api/lib/auth/strategies.js +144 -0
  89. package/src/app/ui/editor-api/lib/auth/tokens.js +138 -0
  90. package/src/app/ui/editor-api/lib/auth/users.js +122 -0
  91. package/src/app/ui/editor-api/lib/editor/comms.js +247 -0
  92. package/src/app/ui/editor-api/lib/editor/credentials.js +22 -0
  93. package/src/app/ui/editor-api/lib/editor/index.js +234 -0
  94. package/src/app/ui/editor-api/lib/editor/library.js +69 -0
  95. package/src/app/ui/editor-api/lib/editor/locales.js +37 -0
  96. package/src/app/ui/editor-api/lib/editor/projects.js +497 -0
  97. package/src/app/ui/editor-api/lib/editor/settings.js +118 -0
  98. package/src/app/ui/editor-api/lib/editor/sshkeys.js +87 -0
  99. package/src/app/ui/editor-api/lib/editor/theme.js +184 -0
  100. package/src/app/ui/editor-api/lib/editor/ui.js +149 -0
  101. package/src/app/ui/editor-api/lib/index.js +149 -0
  102. package/src/app/ui/editor-api/lib/runner/index.js +81 -0
  103. package/src/app/ui/editor-api/lib/util.js +51 -0
  104. package/src/app/ui/editor-client/README.md +10 -0
  105. package/src/app/ui/editor-client/constants.js +5 -0
  106. package/src/app/ui/editor-client/index.js +3 -0
  107. package/src/app/ui/editor-client/public/favicon.ico +0 -0
  108. package/src/app/ui/editor-client/public/red/images/bolt.png +0 -0
  109. package/src/app/ui/editor-client/public/red/images/debugger/continue-full.png +0 -0
  110. package/src/app/ui/editor-client/public/red/images/debugger/continue-outline.png +0 -0
  111. package/src/app/ui/editor-client/public/red/images/debugger/pause.png +0 -0
  112. package/src/app/ui/editor-client/public/red/images/debugger/restart.png +0 -0
  113. package/src/app/ui/editor-client/public/red/images/debugger/stepover.png +0 -0
  114. package/src/app/ui/editor-client/public/red/images/debugger/stop.png +0 -0
  115. package/src/app/ui/editor-client/public/red/images/deploy-flows-o.png +0 -0
  116. package/src/app/ui/editor-client/public/red/images/deploy-flows.png +0 -0
  117. package/src/app/ui/editor-client/public/red/images/deploy-full-o.png +0 -0
  118. package/src/app/ui/editor-client/public/red/images/deploy-full.png +0 -0
  119. package/src/app/ui/editor-client/public/red/images/deploy-nodes-o.png +0 -0
  120. package/src/app/ui/editor-client/public/red/images/deploy-nodes.png +0 -0
  121. package/src/app/ui/editor-client/public/red/images/deploy-reload.png +0 -0
  122. package/src/app/ui/editor-client/public/red/images/grip.png +0 -0
  123. package/src/app/ui/editor-client/public/red/images/icons/arrow-in.png +0 -0
  124. package/src/app/ui/editor-client/public/red/images/icons/bolt.png +0 -0
  125. package/src/app/ui/editor-client/public/red/images/icons/node-changed.png +0 -0
  126. package/src/app/ui/editor-client/public/red/images/icons/node-error.png +0 -0
  127. package/src/app/ui/editor-client/public/red/images/icons/node-play.png +0 -0
  128. package/src/app/ui/editor-client/public/red/images/kumologica-app.png +0 -0
  129. package/src/app/ui/editor-client/public/red/images/node-red-256.png +0 -0
  130. package/src/app/ui/editor-client/public/red/images/node-red-icon-black.svg +9 -0
  131. package/src/app/ui/editor-client/public/red/images/node-red-icon.svg +33 -0
  132. package/src/app/ui/editor-client/public/red/images/node-red.png +0 -0
  133. package/src/app/ui/editor-client/public/red/images/pw_maze_white.png +0 -0
  134. package/src/app/ui/editor-client/public/red/images/spin.svg +41 -0
  135. package/src/app/ui/editor-client/public/red/images/spinner.gif +0 -0
  136. package/src/app/ui/editor-client/public/red/images/subflow_tab.png +0 -0
  137. package/src/app/ui/editor-client/public/red/images/test-icon.png +0 -0
  138. package/src/app/ui/editor-client/public/red/images/typedInput/09.png +0 -0
  139. package/src/app/ui/editor-client/public/red/images/typedInput/az.png +0 -0
  140. package/src/app/ui/editor-client/public/red/images/typedInput/bin.png +0 -0
  141. package/src/app/ui/editor-client/public/red/images/typedInput/bool.png +0 -0
  142. package/src/app/ui/editor-client/public/red/images/typedInput/env.png +0 -0
  143. package/src/app/ui/editor-client/public/red/images/typedInput/expr.png +0 -0
  144. package/src/app/ui/editor-client/public/red/images/typedInput/json.png +0 -0
  145. package/src/app/ui/editor-client/public/red/images/typedInput/re.png +0 -0
  146. package/src/app/ui/editor-client/public/red/keymap.json +54 -0
  147. package/src/app/ui/editor-client/public/red/main-modals.js +14 -0
  148. package/src/app/ui/editor-client/public/red/main-modals.min.js +16 -0
  149. package/src/app/ui/editor-client/public/red/main.js +10 -0
  150. package/src/app/ui/editor-client/public/red/main.min.js +16 -0
  151. package/src/app/ui/editor-client/public/red/red.js +44903 -0
  152. package/src/app/ui/editor-client/public/red/red.min.js +16 -0
  153. package/src/app/ui/editor-client/public/red/style.min.css +24 -0
  154. package/src/app/ui/editor-client/public/vendor/ace/LICENSE +24 -0
  155. package/src/app/ui/editor-client/public/vendor/ace/ace.js +17 -0
  156. package/src/app/ui/editor-client/public/vendor/ace/ext-language_tools.js +8 -0
  157. package/src/app/ui/editor-client/public/vendor/ace/ext-searchbox.js +8 -0
  158. package/src/app/ui/editor-client/public/vendor/ace/mode-css.js +8 -0
  159. package/src/app/ui/editor-client/public/vendor/ace/mode-handlebars.js +8 -0
  160. package/src/app/ui/editor-client/public/vendor/ace/mode-html.js +8 -0
  161. package/src/app/ui/editor-client/public/vendor/ace/mode-javascript.js +8 -0
  162. package/src/app/ui/editor-client/public/vendor/ace/mode-json.js +8 -0
  163. package/src/app/ui/editor-client/public/vendor/ace/mode-jsonata.js +1 -0
  164. package/src/app/ui/editor-client/public/vendor/ace/mode-markdown.js +8 -0
  165. package/src/app/ui/editor-client/public/vendor/ace/mode-properties.js +8 -0
  166. package/src/app/ui/editor-client/public/vendor/ace/mode-python.js +8 -0
  167. package/src/app/ui/editor-client/public/vendor/ace/mode-sql.js +8 -0
  168. package/src/app/ui/editor-client/public/vendor/ace/mode-swift.js +8 -0
  169. package/src/app/ui/editor-client/public/vendor/ace/mode-text.js +8 -0
  170. package/src/app/ui/editor-client/public/vendor/ace/mode-xml.js +8 -0
  171. package/src/app/ui/editor-client/public/vendor/ace/mode-yaml.js +8 -0
  172. package/src/app/ui/editor-client/public/vendor/ace/snippets/css.js +8 -0
  173. package/src/app/ui/editor-client/public/vendor/ace/snippets/handlebars.js +8 -0
  174. package/src/app/ui/editor-client/public/vendor/ace/snippets/html.js +8 -0
  175. package/src/app/ui/editor-client/public/vendor/ace/snippets/javascript.js +8 -0
  176. package/src/app/ui/editor-client/public/vendor/ace/snippets/json.js +8 -0
  177. package/src/app/ui/editor-client/public/vendor/ace/snippets/jsonata.js +1 -0
  178. package/src/app/ui/editor-client/public/vendor/ace/snippets/markdown.js +8 -0
  179. package/src/app/ui/editor-client/public/vendor/ace/snippets/properties.js +8 -0
  180. package/src/app/ui/editor-client/public/vendor/ace/snippets/python.js +8 -0
  181. package/src/app/ui/editor-client/public/vendor/ace/snippets/sql.js +8 -0
  182. package/src/app/ui/editor-client/public/vendor/ace/snippets/swift.js +8 -0
  183. package/src/app/ui/editor-client/public/vendor/ace/snippets/text.js +8 -0
  184. package/src/app/ui/editor-client/public/vendor/ace/snippets/xml.js +8 -0
  185. package/src/app/ui/editor-client/public/vendor/ace/snippets/yaml.js +8 -0
  186. package/src/app/ui/editor-client/public/vendor/ace/theme-chrome.js +8 -0
  187. package/src/app/ui/editor-client/public/vendor/ace/theme-tomorrow.js +8 -0
  188. package/src/app/ui/editor-client/public/vendor/ace/worker-css.js +1 -0
  189. package/src/app/ui/editor-client/public/vendor/ace/worker-html.js +1 -0
  190. package/src/app/ui/editor-client/public/vendor/ace/worker-javascript.js +1 -0
  191. package/src/app/ui/editor-client/public/vendor/ace/worker-json.js +1 -0
  192. package/src/app/ui/editor-client/public/vendor/ace/worker-jsonata.js +2140 -0
  193. package/src/app/ui/editor-client/public/vendor/ace/worker-xml.js +1 -0
  194. package/src/app/ui/editor-client/public/vendor/beautifyjs/beautify.min.js +1 -0
  195. package/src/app/ui/editor-client/public/vendor/bootstrap/css/bootstrap.min.css +9 -0
  196. package/src/app/ui/editor-client/public/vendor/bootstrap/img/glyphicons-halflings-white.png +0 -0
  197. package/src/app/ui/editor-client/public/vendor/bootstrap/img/glyphicons-halflings.png +0 -0
  198. package/src/app/ui/editor-client/public/vendor/code-mirror/addon/active-line.js +72 -0
  199. package/src/app/ui/editor-client/public/vendor/code-mirror/addon/coffeescript-lint.js +47 -0
  200. package/src/app/ui/editor-client/public/vendor/code-mirror/addon/javascript-hint.js +157 -0
  201. package/src/app/ui/editor-client/public/vendor/code-mirror/addon/javascript-lint.js +63 -0
  202. package/src/app/ui/editor-client/public/vendor/code-mirror/addon/jshint.js +29591 -0
  203. package/src/app/ui/editor-client/public/vendor/code-mirror/addon/lint.css +73 -0
  204. package/src/app/ui/editor-client/public/vendor/code-mirror/addon/lint.js +252 -0
  205. package/src/app/ui/editor-client/public/vendor/code-mirror/addon/show-hint.css +36 -0
  206. package/src/app/ui/editor-client/public/vendor/code-mirror/addon/show-hint.js +460 -0
  207. package/src/app/ui/editor-client/public/vendor/code-mirror/addon/sql-hint.js +304 -0
  208. package/src/app/ui/editor-client/public/vendor/code-mirror/lib/codemirror.css +350 -0
  209. package/src/app/ui/editor-client/public/vendor/code-mirror/lib/codemirror.js +9800 -0
  210. package/src/app/ui/editor-client/public/vendor/code-mirror/mode/javascript.js +927 -0
  211. package/src/app/ui/editor-client/public/vendor/code-mirror/mode/sql.js +494 -0
  212. package/src/app/ui/editor-client/public/vendor/code-mirror/theme/base16-dark.css +38 -0
  213. package/src/app/ui/editor-client/public/vendor/code-mirror/theme/monokai.css +42 -0
  214. package/src/app/ui/editor-client/public/vendor/code-mirror/theme/solarized.css +168 -0
  215. package/src/app/ui/editor-client/public/vendor/d3-context-menu/d3-context-menu.css +43 -0
  216. package/src/app/ui/editor-client/public/vendor/d3-context-menu/d3-context-menu.js +87 -0
  217. package/src/app/ui/editor-client/public/vendor/easy-json-schema/index.js +88 -0
  218. package/src/app/ui/editor-client/public/vendor/font-awesome/css/font-awesome.min.css +4 -0
  219. package/src/app/ui/editor-client/public/vendor/font-awesome/fonts/FontAwesome.otf +0 -0
  220. package/src/app/ui/editor-client/public/vendor/font-awesome/fonts/fontawesome-webfont.eot +0 -0
  221. package/src/app/ui/editor-client/public/vendor/font-awesome/fonts/fontawesome-webfont.svg +2671 -0
  222. package/src/app/ui/editor-client/public/vendor/font-awesome/fonts/fontawesome-webfont.ttf +0 -0
  223. package/src/app/ui/editor-client/public/vendor/font-awesome/fonts/fontawesome-webfont.woff +0 -0
  224. package/src/app/ui/editor-client/public/vendor/font-awesome/fonts/fontawesome-webfont.woff2 +0 -0
  225. package/src/app/ui/editor-client/public/vendor/icofont/fonts/icofont.eot +0 -0
  226. package/src/app/ui/editor-client/public/vendor/icofont/fonts/icofont.svg +2105 -0
  227. package/src/app/ui/editor-client/public/vendor/icofont/fonts/icofont.ttf +0 -0
  228. package/src/app/ui/editor-client/public/vendor/icofont/fonts/icofont.woff +0 -0
  229. package/src/app/ui/editor-client/public/vendor/icofont/fonts/icofont.woff2 +0 -0
  230. package/src/app/ui/editor-client/public/vendor/icofont/icofont.min.css +7 -0
  231. package/src/app/ui/editor-client/public/vendor/jquery/css/smoothness/images/animated-overlay.gif +0 -0
  232. package/src/app/ui/editor-client/public/vendor/jquery/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  233. package/src/app/ui/editor-client/public/vendor/jquery/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  234. package/src/app/ui/editor-client/public/vendor/jquery/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  235. package/src/app/ui/editor-client/public/vendor/jquery/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  236. package/src/app/ui/editor-client/public/vendor/jquery/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  237. package/src/app/ui/editor-client/public/vendor/jquery/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  238. package/src/app/ui/editor-client/public/vendor/jquery/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  239. package/src/app/ui/editor-client/public/vendor/jquery/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  240. package/src/app/ui/editor-client/public/vendor/jquery/css/smoothness/images/ui-icons_222222_256x240.png +0 -0
  241. package/src/app/ui/editor-client/public/vendor/jquery/css/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  242. package/src/app/ui/editor-client/public/vendor/jquery/css/smoothness/images/ui-icons_454545_256x240.png +0 -0
  243. package/src/app/ui/editor-client/public/vendor/jquery/css/smoothness/images/ui-icons_888888_256x240.png +0 -0
  244. package/src/app/ui/editor-client/public/vendor/jquery/css/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  245. package/src/app/ui/editor-client/public/vendor/jquery/css/smoothness/jquery-ui-1.10.3.custom.min.css +5 -0
  246. package/src/app/ui/editor-client/public/vendor/jsonata/jsonata.min.js +183 -0
  247. package/src/app/ui/editor-client/public/vendor/misc/toggleswitch.css +181 -0
  248. package/src/app/ui/editor-client/public/vendor/misc/toggleswitch.js +48 -0
  249. package/src/app/ui/editor-client/public/vendor/simplemde/simplemde.min.css +7 -0
  250. package/src/app/ui/editor-client/public/vendor/simplemde/simplemde.min.js +15 -0
  251. package/src/app/ui/editor-client/public/vendor/vendor.css +0 -0
  252. package/src/app/ui/editor-client/public/vendor/vendor.js +125 -0
  253. package/src/app/ui/editor-client/public/vendor/xterm/lib/xterm.js +2 -0
  254. package/src/app/ui/editor-client/src/ace/README.md +50 -0
  255. package/src/app/ui/editor-client/src/ace/mode/nrjavascript.js +35 -0
  256. package/src/app/ui/editor-client/src/ace/mode/nrjavascript_worker.js +189 -0
  257. package/src/app/ui/editor-client/src/favicon.ico +0 -0
  258. package/src/app/ui/editor-client/src/images/bolt.png +0 -0
  259. package/src/app/ui/editor-client/src/images/debugger/continue-full.png +0 -0
  260. package/src/app/ui/editor-client/src/images/debugger/continue-outline.png +0 -0
  261. package/src/app/ui/editor-client/src/images/debugger/pause.png +0 -0
  262. package/src/app/ui/editor-client/src/images/debugger/restart.png +0 -0
  263. package/src/app/ui/editor-client/src/images/debugger/stepover.png +0 -0
  264. package/src/app/ui/editor-client/src/images/debugger/stop.png +0 -0
  265. package/src/app/ui/editor-client/src/images/deploy-flows-o.png +0 -0
  266. package/src/app/ui/editor-client/src/images/deploy-flows.png +0 -0
  267. package/src/app/ui/editor-client/src/images/deploy-full-o.png +0 -0
  268. package/src/app/ui/editor-client/src/images/deploy-full.png +0 -0
  269. package/src/app/ui/editor-client/src/images/deploy-nodes-o.png +0 -0
  270. package/src/app/ui/editor-client/src/images/deploy-nodes.png +0 -0
  271. package/src/app/ui/editor-client/src/images/deploy-reload.png +0 -0
  272. package/src/app/ui/editor-client/src/images/grip.png +0 -0
  273. package/src/app/ui/editor-client/src/images/icons/arrow-in.png +0 -0
  274. package/src/app/ui/editor-client/src/images/icons/bolt.png +0 -0
  275. package/src/app/ui/editor-client/src/images/icons/node-changed.png +0 -0
  276. package/src/app/ui/editor-client/src/images/icons/node-error.png +0 -0
  277. package/src/app/ui/editor-client/src/images/icons/node-play.png +0 -0
  278. package/src/app/ui/editor-client/src/images/kumologica-app.png +0 -0
  279. package/src/app/ui/editor-client/src/images/node-red-256.png +0 -0
  280. package/src/app/ui/editor-client/src/images/node-red-icon-black.svg +9 -0
  281. package/src/app/ui/editor-client/src/images/node-red-icon.svg +33 -0
  282. package/src/app/ui/editor-client/src/images/node-red.png +0 -0
  283. package/src/app/ui/editor-client/src/images/pw_maze_white.png +0 -0
  284. package/src/app/ui/editor-client/src/images/spin.svg +41 -0
  285. package/src/app/ui/editor-client/src/images/spinner.gif +0 -0
  286. package/src/app/ui/editor-client/src/images/subflow_tab.png +0 -0
  287. package/src/app/ui/editor-client/src/images/test-icon.png +0 -0
  288. package/src/app/ui/editor-client/src/images/typedInput/09.png +0 -0
  289. package/src/app/ui/editor-client/src/images/typedInput/az.png +0 -0
  290. package/src/app/ui/editor-client/src/images/typedInput/bin.png +0 -0
  291. package/src/app/ui/editor-client/src/images/typedInput/bool.png +0 -0
  292. package/src/app/ui/editor-client/src/images/typedInput/env.png +0 -0
  293. package/src/app/ui/editor-client/src/images/typedInput/expr.png +0 -0
  294. package/src/app/ui/editor-client/src/images/typedInput/json.png +0 -0
  295. package/src/app/ui/editor-client/src/images/typedInput/re.png +0 -0
  296. package/src/app/ui/editor-client/src/js/comms.js +174 -0
  297. package/src/app/ui/editor-client/src/js/events.js +39 -0
  298. package/src/app/ui/editor-client/src/js/font-awesome.js +818 -0
  299. package/src/app/ui/editor-client/src/js/history.js +337 -0
  300. package/src/app/ui/editor-client/src/js/i18n.js +81 -0
  301. package/src/app/ui/editor-client/src/js/jquery-addons.js +21 -0
  302. package/src/app/ui/editor-client/src/js/keymap.json +54 -0
  303. package/src/app/ui/editor-client/src/js/main-modals.js +14 -0
  304. package/src/app/ui/editor-client/src/js/main.js +10 -0
  305. package/src/app/ui/editor-client/src/js/modals/modal-home.js +162 -0
  306. package/src/app/ui/editor-client/src/js/modals/modal-new-project.js +86 -0
  307. package/src/app/ui/editor-client/src/js/modals/modal-node-library.js +255 -0
  308. package/src/app/ui/editor-client/src/js/modals/modal-welcome.js +102 -0
  309. package/src/app/ui/editor-client/src/js/nodes.js +1736 -0
  310. package/src/app/ui/editor-client/src/js/red.js +704 -0
  311. package/src/app/ui/editor-client/src/js/settings.js +275 -0
  312. package/src/app/ui/editor-client/src/js/text/bidi.js +116 -0
  313. package/src/app/ui/editor-client/src/js/text/format.js +1316 -0
  314. package/src/app/ui/editor-client/src/js/ui/actions.js +39 -0
  315. package/src/app/ui/editor-client/src/js/ui/clipboard.js +510 -0
  316. package/src/app/ui/editor-client/src/js/ui/common/checkboxSet.js +117 -0
  317. package/src/app/ui/editor-client/src/js/ui/common/editableList.js +322 -0
  318. package/src/app/ui/editor-client/src/js/ui/common/menu.js +277 -0
  319. package/src/app/ui/editor-client/src/js/ui/common/panels.js +104 -0
  320. package/src/app/ui/editor-client/src/js/ui/common/popover.js +268 -0
  321. package/src/app/ui/editor-client/src/js/ui/common/searchBox.js +98 -0
  322. package/src/app/ui/editor-client/src/js/ui/common/stack.js +184 -0
  323. package/src/app/ui/editor-client/src/js/ui/common/tabs.js +730 -0
  324. package/src/app/ui/editor-client/src/js/ui/common/treeList.js +170 -0
  325. package/src/app/ui/editor-client/src/js/ui/common/typedInput.js +819 -0
  326. package/src/app/ui/editor-client/src/js/ui/common/typedInputLong.js +829 -0
  327. package/src/app/ui/editor-client/src/js/ui/deploy.js +422 -0
  328. package/src/app/ui/editor-client/src/js/ui/diff.js +2225 -0
  329. package/src/app/ui/editor-client/src/js/ui/editor.js +3020 -0
  330. package/src/app/ui/editor-client/src/js/ui/editors/buffer.js +195 -0
  331. package/src/app/ui/editor-client/src/js/ui/editors/expression.js +627 -0
  332. package/src/app/ui/editor-client/src/js/ui/editors/js.js +89 -0
  333. package/src/app/ui/editor-client/src/js/ui/editors/json.js +107 -0
  334. package/src/app/ui/editor-client/src/js/ui/editors/markdown.js +267 -0
  335. package/src/app/ui/editor-client/src/js/ui/editors/string.js +75 -0
  336. package/src/app/ui/editor-client/src/js/ui/event-log.js +107 -0
  337. package/src/app/ui/editor-client/src/js/ui/header.js +372 -0
  338. package/src/app/ui/editor-client/src/js/ui/keyboard.js +565 -0
  339. package/src/app/ui/editor-client/src/js/ui/library.js +570 -0
  340. package/src/app/ui/editor-client/src/js/ui/logviewer.js +116 -0
  341. package/src/app/ui/editor-client/src/js/ui/notifications.js +282 -0
  342. package/src/app/ui/editor-client/src/js/ui/palette-editor.js +1061 -0
  343. package/src/app/ui/editor-client/src/js/ui/palette.js +788 -0
  344. package/src/app/ui/editor-client/src/js/ui/project-info.js +232 -0
  345. package/src/app/ui/editor-client/src/js/ui/projects/projectSettings.js +1651 -0
  346. package/src/app/ui/editor-client/src/js/ui/projects/projectUserSettings.js +404 -0
  347. package/src/app/ui/editor-client/src/js/ui/projects/projects.js +2395 -0
  348. package/src/app/ui/editor-client/src/js/ui/projects/tab-versionControl.js +1383 -0
  349. package/src/app/ui/editor-client/src/js/ui/search.js +366 -0
  350. package/src/app/ui/editor-client/src/js/ui/sidebar.js +409 -0
  351. package/src/app/ui/editor-client/src/js/ui/state.js +14 -0
  352. package/src/app/ui/editor-client/src/js/ui/subflow.js +748 -0
  353. package/src/app/ui/editor-client/src/js/ui/tab-awsDeploy.js +1427 -0
  354. package/src/app/ui/editor-client/src/js/ui/tab-azure.js +852 -0
  355. package/src/app/ui/editor-client/src/js/ui/tab-config.js +452 -0
  356. package/src/app/ui/editor-client/src/js/ui/tab-context.js +406 -0
  357. package/src/app/ui/editor-client/src/js/ui/tab-info.js +661 -0
  358. package/src/app/ui/editor-client/src/js/ui/tab-kumohub.js +800 -0
  359. package/src/app/ui/editor-client/src/js/ui/tab-nodeInfo.js +60 -0
  360. package/src/app/ui/editor-client/src/js/ui/tab-test.js +915 -0
  361. package/src/app/ui/editor-client/src/js/ui/terminal.js +240 -0
  362. package/src/app/ui/editor-client/src/js/ui/touch/radialMenu.js +170 -0
  363. package/src/app/ui/editor-client/src/js/ui/tray.js +411 -0
  364. package/src/app/ui/editor-client/src/js/ui/typeSearch.js +411 -0
  365. package/src/app/ui/editor-client/src/js/ui/ui-settings.js +422 -0
  366. package/src/app/ui/editor-client/src/js/ui/update-panel.js +84 -0
  367. package/src/app/ui/editor-client/src/js/ui/userSettings.js +673 -0
  368. package/src/app/ui/editor-client/src/js/ui/utils.js +1287 -0
  369. package/src/app/ui/editor-client/src/js/ui/view-navigator.js +169 -0
  370. package/src/app/ui/editor-client/src/js/ui/view-tools.js +123 -0
  371. package/src/app/ui/editor-client/src/js/ui/view.js +5333 -0
  372. package/src/app/ui/editor-client/src/js/ui/workspaces.js +498 -0
  373. package/src/app/ui/editor-client/src/js/user.js +282 -0
  374. package/src/app/ui/editor-client/src/js/validators.js +54 -0
  375. package/src/app/ui/editor-client/src/kumologica-app.png +0 -0
  376. package/src/app/ui/editor-client/src/sass/ace.scss +29 -0
  377. package/src/app/ui/editor-client/src/sass/bootstrap.scss +21 -0
  378. package/src/app/ui/editor-client/src/sass/colors.scss +76 -0
  379. package/src/app/ui/editor-client/src/sass/debug.scss +383 -0
  380. package/src/app/ui/editor-client/src/sass/diff.scss +695 -0
  381. package/src/app/ui/editor-client/src/sass/dragdrop.scss +37 -0
  382. package/src/app/ui/editor-client/src/sass/dropdownMenu.scss +93 -0
  383. package/src/app/ui/editor-client/src/sass/editor.scss +683 -0
  384. package/src/app/ui/editor-client/src/sass/flow.scss +330 -0
  385. package/src/app/ui/editor-client/src/sass/forms.scss +1093 -0
  386. package/src/app/ui/editor-client/src/sass/header.scss +502 -0
  387. package/src/app/ui/editor-client/src/sass/jquery.scss +152 -0
  388. package/src/app/ui/editor-client/src/sass/keyboard.scss +136 -0
  389. package/src/app/ui/editor-client/src/sass/library.scss +54 -0
  390. package/src/app/ui/editor-client/src/sass/mixins.scss +283 -0
  391. package/src/app/ui/editor-client/src/sass/modals/modalHome.scss +138 -0
  392. package/src/app/ui/editor-client/src/sass/modals/modalNewProject.scss +96 -0
  393. package/src/app/ui/editor-client/src/sass/modals/modalNodeLibrary.scss +131 -0
  394. package/src/app/ui/editor-client/src/sass/modals/modalWelcome.scss +102 -0
  395. package/src/app/ui/editor-client/src/sass/notifications.scss +118 -0
  396. package/src/app/ui/editor-client/src/sass/palette-editor.scss +275 -0
  397. package/src/app/ui/editor-client/src/sass/palette.scss +279 -0
  398. package/src/app/ui/editor-client/src/sass/panels.scss +61 -0
  399. package/src/app/ui/editor-client/src/sass/popover.scss +166 -0
  400. package/src/app/ui/editor-client/src/sass/project-info.scss +74 -0
  401. package/src/app/ui/editor-client/src/sass/projects.scss +875 -0
  402. package/src/app/ui/editor-client/src/sass/search.scss +201 -0
  403. package/src/app/ui/editor-client/src/sass/sidebar.scss +201 -0
  404. package/src/app/ui/editor-client/src/sass/style.scss +170 -0
  405. package/src/app/ui/editor-client/src/sass/tab-azure.scss +68 -0
  406. package/src/app/ui/editor-client/src/sass/tab-cloud.scss +67 -0
  407. package/src/app/ui/editor-client/src/sass/tab-config.scss +100 -0
  408. package/src/app/ui/editor-client/src/sass/tab-context.scss +54 -0
  409. package/src/app/ui/editor-client/src/sass/tab-info.scss +307 -0
  410. package/src/app/ui/editor-client/src/sass/tab-kumohub.scss +68 -0
  411. package/src/app/ui/editor-client/src/sass/tab-test.scss +257 -0
  412. package/src/app/ui/editor-client/src/sass/tabs.scss +395 -0
  413. package/src/app/ui/editor-client/src/sass/terminal.scss +246 -0
  414. package/src/app/ui/editor-client/src/sass/ui/common/checkboxSet.scss +29 -0
  415. package/src/app/ui/editor-client/src/sass/ui/common/editableList.scss +81 -0
  416. package/src/app/ui/editor-client/src/sass/ui/common/nodeList.scss +65 -0
  417. package/src/app/ui/editor-client/src/sass/ui/common/searchBox.scss +77 -0
  418. package/src/app/ui/editor-client/src/sass/ui/common/stack.scss +26 -0
  419. package/src/app/ui/editor-client/src/sass/ui/common/treeList.scss +108 -0
  420. package/src/app/ui/editor-client/src/sass/ui/common/typedInput.scss +181 -0
  421. package/src/app/ui/editor-client/src/sass/ui/common/typedInputLong.scss +183 -0
  422. package/src/app/ui/editor-client/src/sass/ui-settings.scss +119 -0
  423. package/src/app/ui/editor-client/src/sass/update-panel.scss +18 -0
  424. package/src/app/ui/editor-client/src/sass/userSettings.scss +93 -0
  425. package/src/app/ui/editor-client/src/sass/widgetStyle.scss +23 -0
  426. package/src/app/ui/editor-client/src/sass/workspace.scss +123 -0
  427. package/src/app/ui/editor-client/src/sass/workspaceToolbar.scss +85 -0
  428. package/src/app/ui/editor-client/src/vendor/ace/LICENSE +24 -0
  429. package/src/app/ui/editor-client/src/vendor/ace/ace.js +17 -0
  430. package/src/app/ui/editor-client/src/vendor/ace/ext-language_tools.js +8 -0
  431. package/src/app/ui/editor-client/src/vendor/ace/ext-searchbox.js +8 -0
  432. package/src/app/ui/editor-client/src/vendor/ace/mode-css.js +8 -0
  433. package/src/app/ui/editor-client/src/vendor/ace/mode-handlebars.js +8 -0
  434. package/src/app/ui/editor-client/src/vendor/ace/mode-html.js +8 -0
  435. package/src/app/ui/editor-client/src/vendor/ace/mode-javascript.js +8 -0
  436. package/src/app/ui/editor-client/src/vendor/ace/mode-json.js +8 -0
  437. package/src/app/ui/editor-client/src/vendor/ace/mode-markdown.js +8 -0
  438. package/src/app/ui/editor-client/src/vendor/ace/mode-properties.js +8 -0
  439. package/src/app/ui/editor-client/src/vendor/ace/mode-python.js +8 -0
  440. package/src/app/ui/editor-client/src/vendor/ace/mode-sql.js +8 -0
  441. package/src/app/ui/editor-client/src/vendor/ace/mode-swift.js +8 -0
  442. package/src/app/ui/editor-client/src/vendor/ace/mode-text.js +8 -0
  443. package/src/app/ui/editor-client/src/vendor/ace/mode-xml.js +8 -0
  444. package/src/app/ui/editor-client/src/vendor/ace/mode-yaml.js +8 -0
  445. package/src/app/ui/editor-client/src/vendor/ace/snippets/css.js +8 -0
  446. package/src/app/ui/editor-client/src/vendor/ace/snippets/handlebars.js +8 -0
  447. package/src/app/ui/editor-client/src/vendor/ace/snippets/html.js +8 -0
  448. package/src/app/ui/editor-client/src/vendor/ace/snippets/javascript.js +8 -0
  449. package/src/app/ui/editor-client/src/vendor/ace/snippets/json.js +8 -0
  450. package/src/app/ui/editor-client/src/vendor/ace/snippets/markdown.js +8 -0
  451. package/src/app/ui/editor-client/src/vendor/ace/snippets/properties.js +8 -0
  452. package/src/app/ui/editor-client/src/vendor/ace/snippets/python.js +8 -0
  453. package/src/app/ui/editor-client/src/vendor/ace/snippets/sql.js +8 -0
  454. package/src/app/ui/editor-client/src/vendor/ace/snippets/swift.js +8 -0
  455. package/src/app/ui/editor-client/src/vendor/ace/snippets/text.js +8 -0
  456. package/src/app/ui/editor-client/src/vendor/ace/snippets/xml.js +8 -0
  457. package/src/app/ui/editor-client/src/vendor/ace/snippets/yaml.js +8 -0
  458. package/src/app/ui/editor-client/src/vendor/ace/theme-chrome.js +8 -0
  459. package/src/app/ui/editor-client/src/vendor/ace/theme-tomorrow.js +8 -0
  460. package/src/app/ui/editor-client/src/vendor/ace/worker-css.js +1 -0
  461. package/src/app/ui/editor-client/src/vendor/ace/worker-html.js +1 -0
  462. package/src/app/ui/editor-client/src/vendor/ace/worker-javascript.js +1 -0
  463. package/src/app/ui/editor-client/src/vendor/ace/worker-json.js +1 -0
  464. package/src/app/ui/editor-client/src/vendor/ace/worker-xml.js +1 -0
  465. package/src/app/ui/editor-client/src/vendor/beautifyjs/beautify.min.js +1 -0
  466. package/src/app/ui/editor-client/src/vendor/bootstrap/css/bootstrap.css +5406 -0
  467. package/src/app/ui/editor-client/src/vendor/bootstrap/css/bootstrap.min.css +9 -0
  468. package/src/app/ui/editor-client/src/vendor/bootstrap/img/glyphicons-halflings-white.png +0 -0
  469. package/src/app/ui/editor-client/src/vendor/bootstrap/img/glyphicons-halflings.png +0 -0
  470. package/src/app/ui/editor-client/src/vendor/bootstrap/js/bootstrap.min.js +6 -0
  471. package/src/app/ui/editor-client/src/vendor/code-mirror/addon/active-line.js +72 -0
  472. package/src/app/ui/editor-client/src/vendor/code-mirror/addon/coffeescript-lint.js +47 -0
  473. package/src/app/ui/editor-client/src/vendor/code-mirror/addon/javascript-hint.js +157 -0
  474. package/src/app/ui/editor-client/src/vendor/code-mirror/addon/javascript-lint.js +63 -0
  475. package/src/app/ui/editor-client/src/vendor/code-mirror/addon/jshint.js +29591 -0
  476. package/src/app/ui/editor-client/src/vendor/code-mirror/addon/lint.css +73 -0
  477. package/src/app/ui/editor-client/src/vendor/code-mirror/addon/lint.js +252 -0
  478. package/src/app/ui/editor-client/src/vendor/code-mirror/addon/show-hint.css +36 -0
  479. package/src/app/ui/editor-client/src/vendor/code-mirror/addon/show-hint.js +460 -0
  480. package/src/app/ui/editor-client/src/vendor/code-mirror/addon/sql-hint.js +304 -0
  481. package/src/app/ui/editor-client/src/vendor/code-mirror/lib/codemirror.css +350 -0
  482. package/src/app/ui/editor-client/src/vendor/code-mirror/lib/codemirror.js +9800 -0
  483. package/src/app/ui/editor-client/src/vendor/code-mirror/mode/javascript.js +927 -0
  484. package/src/app/ui/editor-client/src/vendor/code-mirror/mode/sql.js +494 -0
  485. package/src/app/ui/editor-client/src/vendor/code-mirror/theme/base16-dark.css +38 -0
  486. package/src/app/ui/editor-client/src/vendor/code-mirror/theme/monokai.css +42 -0
  487. package/src/app/ui/editor-client/src/vendor/code-mirror/theme/solarized.css +168 -0
  488. package/src/app/ui/editor-client/src/vendor/d3/d3.v3.min.js +4 -0
  489. package/src/app/ui/editor-client/src/vendor/d3/d3.v4.min.js +2 -0
  490. package/src/app/ui/editor-client/src/vendor/d3-context-menu/d3-context-menu.css +43 -0
  491. package/src/app/ui/editor-client/src/vendor/d3-context-menu/d3-context-menu.js +87 -0
  492. package/src/app/ui/editor-client/src/vendor/easy-json-schema/index.js +88 -0
  493. package/src/app/ui/editor-client/src/vendor/font-awesome/css/font-awesome.min.css +4 -0
  494. package/src/app/ui/editor-client/src/vendor/font-awesome/fonts/FontAwesome.otf +0 -0
  495. package/src/app/ui/editor-client/src/vendor/font-awesome/fonts/fontawesome-webfont.eot +0 -0
  496. package/src/app/ui/editor-client/src/vendor/font-awesome/fonts/fontawesome-webfont.svg +2671 -0
  497. package/src/app/ui/editor-client/src/vendor/font-awesome/fonts/fontawesome-webfont.ttf +0 -0
  498. package/src/app/ui/editor-client/src/vendor/font-awesome/fonts/fontawesome-webfont.woff +0 -0
  499. package/src/app/ui/editor-client/src/vendor/font-awesome/fonts/fontawesome-webfont.woff2 +0 -0
  500. package/src/app/ui/editor-client/src/vendor/i18next/i18next.min.js +5 -0
  501. package/src/app/ui/editor-client/src/vendor/icofont/fonts/icofont.eot +0 -0
  502. package/src/app/ui/editor-client/src/vendor/icofont/fonts/icofont.svg +2105 -0
  503. package/src/app/ui/editor-client/src/vendor/icofont/fonts/icofont.ttf +0 -0
  504. package/src/app/ui/editor-client/src/vendor/icofont/fonts/icofont.woff +0 -0
  505. package/src/app/ui/editor-client/src/vendor/icofont/fonts/icofont.woff2 +0 -0
  506. package/src/app/ui/editor-client/src/vendor/icofont/icofont.min.css +7 -0
  507. package/src/app/ui/editor-client/src/vendor/jquery/css/smoothness/images/animated-overlay.gif +0 -0
  508. package/src/app/ui/editor-client/src/vendor/jquery/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  509. package/src/app/ui/editor-client/src/vendor/jquery/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  510. package/src/app/ui/editor-client/src/vendor/jquery/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  511. package/src/app/ui/editor-client/src/vendor/jquery/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  512. package/src/app/ui/editor-client/src/vendor/jquery/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  513. package/src/app/ui/editor-client/src/vendor/jquery/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  514. package/src/app/ui/editor-client/src/vendor/jquery/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  515. package/src/app/ui/editor-client/src/vendor/jquery/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  516. package/src/app/ui/editor-client/src/vendor/jquery/css/smoothness/images/ui-icons_222222_256x240.png +0 -0
  517. package/src/app/ui/editor-client/src/vendor/jquery/css/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  518. package/src/app/ui/editor-client/src/vendor/jquery/css/smoothness/images/ui-icons_454545_256x240.png +0 -0
  519. package/src/app/ui/editor-client/src/vendor/jquery/css/smoothness/images/ui-icons_888888_256x240.png +0 -0
  520. package/src/app/ui/editor-client/src/vendor/jquery/css/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  521. package/src/app/ui/editor-client/src/vendor/jquery/css/smoothness/jquery-ui-1.10.3.custom.min.css +5 -0
  522. package/src/app/ui/editor-client/src/vendor/jquery/js/jquery-1.11.3.min.js +5 -0
  523. package/src/app/ui/editor-client/src/vendor/jquery/js/jquery-ui-1.10.3.custom.min.js +7 -0
  524. package/src/app/ui/editor-client/src/vendor/jquery/js/jquery.ui.touch-punch.min.js +11 -0
  525. package/src/app/ui/editor-client/src/vendor/jsonata/formatter.js +183 -0
  526. package/src/app/ui/editor-client/src/vendor/jsonata/mode-jsonata.js +134 -0
  527. package/src/app/ui/editor-client/src/vendor/jsonata/snippets-jsonata.js +11 -0
  528. package/src/app/ui/editor-client/src/vendor/jsonata/worker-jsonata.js +2140 -0
  529. package/src/app/ui/editor-client/src/vendor/marked/marked.min.js +6 -0
  530. package/src/app/ui/editor-client/src/vendor/misc/toggleswitch.css +181 -0
  531. package/src/app/ui/editor-client/src/vendor/misc/toggleswitch.js +48 -0
  532. package/src/app/ui/editor-client/templates/index.mst +314 -0
  533. package/src/app/ui/editor-client/templates/modals/modalHome.mst +107 -0
  534. package/src/app/ui/editor-client/templates/modals/modalNewProject.mst +104 -0
  535. package/src/app/ui/editor-client/templates/modals/modalNodeLibrary.mst +72 -0
  536. package/src/app/ui/editor-client/templates/modals/modalWelcome.mst +111 -0
  537. package/src/assets/eula.txt +170 -0
  538. package/src/assets/icon.icns +0 -0
  539. package/src/assets/kumologica-app.png +0 -0
  540. package/src/assets/license_en.txt +170 -0
@@ -0,0 +1,2395 @@
1
+
2
+ RED.projects = (function() {
3
+
4
+ var dialog;
5
+ var dialogBody;
6
+
7
+ var activeProject;
8
+ function reportUnexpectedError(error) {
9
+ var notification;
10
+ if (error.code === 'git_missing_user') {
11
+ notification = RED.notify("<p>"+RED._("projects.errors.no-username-email")+"</p>",{
12
+ fixed: true,
13
+ type:'error',
14
+ buttons: [
15
+ {
16
+ text: RED._("common.label.cancel"),
17
+ click: function() {
18
+ notification.close();
19
+ }
20
+ },
21
+ {
22
+ text: RED._("projects.config-git"),
23
+ click: function() {
24
+ RED.userSettings.show('gitconfig');
25
+ notification.close();
26
+ }
27
+ }
28
+ ]
29
+ })
30
+ } else {
31
+ console.log(error);
32
+ notification = RED.notify("<p>"+RED._("projects.errors.unexpected")+":</p><p>"+error.message+"</p><small>"+RED._("projects.errors.code")+": "+error.code+"</small>",{
33
+ fixed: true,
34
+ modal: true,
35
+ type: 'error',
36
+ buttons: [
37
+ {
38
+ text: RED._("common.label.close"),
39
+ click: function() {
40
+ notification.close();
41
+ }
42
+ }
43
+ ]
44
+ })
45
+ }
46
+ }
47
+ var screens = {};
48
+ function initScreens() {
49
+ var migrateProjectHeader = $('<div class="projects-dialog-screen-start-hero"></div>');
50
+ $('<span><i class="fa fa-files-o fa-2x"></i> &nbsp; &nbsp; <i class="fa fa-long-arrow-right fa-2x"></i> &nbsp; &nbsp; <i class="fa fa-archive fa-2x"></i></span>').appendTo(migrateProjectHeader)
51
+ $('<hr>').appendTo(migrateProjectHeader);
52
+
53
+ var createProjectOptions = {};
54
+
55
+ screens = {
56
+ 'welcome': {
57
+ content: function(options) {
58
+
59
+ var container = $('<div class="projects-dialog-screen-start"></div>');
60
+
61
+ migrateProjectHeader.appendTo(container);
62
+
63
+ var body = $('<div class="projects-dialog-screen-start-body"></div>').appendTo(container);
64
+ $('<p>').text(RED._("projects.welcome.hello")).appendTo(body);
65
+ $('<p>').text(RED._("projects.welcome.desc0")).appendTo(body);
66
+ $('<p>').text(RED._("projects.welcome.desc1")).appendTo(body);
67
+ $('<p>').text(RED._("projects.welcome.desc2")).appendTo(body);
68
+
69
+ var row = $('<div style="text-align: center"></div>').appendTo(body);
70
+ var createAsEmpty = $('<button data-type="empty" class="editor-button projects-dialog-screen-create-type"><i class="fa fa-archive fa-2x"></i><i style="position: absolute;" class="fa fa-asterisk"></i><br/>'+RED._("projects.welcome.create")+'</button>').appendTo(row);
71
+ var createAsClone = $('<button data-type="clone" class="editor-button projects-dialog-screen-create-type"><i class="fa fa-archive fa-2x"></i><i style="position: absolute;" class="fa fa-git"></i><br/>'+RED._("projects.welcome.clone")+'</button>').appendTo(row);
72
+
73
+ createAsEmpty.click(function(e) {
74
+ e.preventDefault();
75
+ createProjectOptions = {
76
+ action: "create"
77
+ }
78
+ show('git-config');
79
+ })
80
+
81
+ createAsClone.click(function(e) {
82
+ e.preventDefault();
83
+ createProjectOptions = {
84
+ action: "clone"
85
+ }
86
+ show('git-config');
87
+ })
88
+
89
+ return container;
90
+ },
91
+ buttons: [
92
+ {
93
+ // id: "clipboard-dialog-cancel",
94
+ text: RED._("projects.welcome.openExistingProject"),
95
+ class: "secondary",
96
+ click: function() {
97
+ createProjectOptions = {
98
+ action: "open"
99
+ }
100
+ show('git-config');
101
+ }
102
+ },
103
+
104
+ {
105
+ // id: "clipboard-dialog-cancel",
106
+ text: RED._("projects.welcome.not-right-now"),
107
+ click: function() {
108
+ createProjectOptions = {};
109
+ $( this ).dialog( "close" );
110
+ }
111
+ }
112
+ ]
113
+ },
114
+ 'git-config': (function() {
115
+ var gitUsernameInput;
116
+ var gitEmailInput;
117
+ return {
118
+ content: function(options) {
119
+ var isGlobalConfig = false;
120
+ var existingGitSettings = RED.settings.get('git');
121
+ if (existingGitSettings && existingGitSettings.user) {
122
+ existingGitSettings = existingGitSettings.user;
123
+ } else if (RED.settings.git && RED.settings.git.globalUser) {
124
+ isGlobalConfig = true;
125
+ existingGitSettings = RED.settings.git.globalUser;
126
+ }
127
+
128
+ var validateForm = function() {
129
+ var name = gitUsernameInput.val().trim();
130
+ var email = gitEmailInput.val().trim();
131
+ var valid = name.length > 0 && email.length > 0;
132
+ $("#projects-dialog-git-config").prop('disabled',!valid).toggleClass('disabled ui-button-disabled ui-state-disabled',!valid);
133
+
134
+ }
135
+
136
+ var container = $('<div class="projects-dialog-screen-start"></div>');
137
+ migrateProjectHeader.appendTo(container);
138
+ var body = $('<div class="projects-dialog-screen-start-body"></div>').appendTo(container);
139
+
140
+ $('<p>').text(RED._("projects.git-config.setup")).appendTo(body);
141
+ $('<p>').text(RED._("projects.git-config.desc0")).appendTo(body);
142
+ $('<p>').text(RED._("projects.git-config.desc1")).appendTo(body);
143
+
144
+ if (isGlobalConfig) {
145
+ $('<p>').text(RED._("projects.git-config.desc2")).appendTo(body);
146
+ }
147
+ $('<p>').text(RED._("projects.git-config.desc3")).appendTo(body);
148
+
149
+ var row = $('<div class="form-row"></div>').appendTo(body);
150
+ $('<label for="">'+RED._("projects.git-config.username")+'</label>').appendTo(row);
151
+ gitUsernameInput = $('<input type="text">').val((existingGitSettings&&existingGitSettings.name)||"").appendTo(row);
152
+ // $('<div style="position:relative;"></div>').text("This does not need to be your real name").appendTo(row);
153
+ gitUsernameInput.on("change keyup paste",validateForm);
154
+
155
+ row = $('<div class="form-row"></div>').appendTo(body);
156
+ $('<label for="">'+RED._("projects.git-config.email")+'</label>').appendTo(row);
157
+ gitEmailInput = $('<input type="text">').val((existingGitSettings&&existingGitSettings.email)||"").appendTo(row);
158
+ gitEmailInput.on("change keyup paste",validateForm);
159
+ // $('<div style="position:relative;"></div>').text("Something something email").appendTo(row);
160
+ setTimeout(function() {
161
+ gitUsernameInput.focus();
162
+ validateForm();
163
+ },50);
164
+ return container;
165
+ },
166
+ buttons: [
167
+ {
168
+ // id: "clipboard-dialog-cancel",
169
+ text: RED._("common.label.back"),
170
+ click: function() {
171
+ show('welcome');
172
+ }
173
+ },
174
+ {
175
+ id: "projects-dialog-git-config",
176
+ text: RED._("common.label.next"),
177
+ class: "primary",
178
+ click: function() {
179
+ var currentGitSettings = RED.settings.get('git') || {};
180
+ currentGitSettings.user = currentGitSettings.user || {};
181
+ currentGitSettings.user.name = gitUsernameInput.val();
182
+ currentGitSettings.user.email = gitEmailInput.val();
183
+ RED.settings.set('git', currentGitSettings);
184
+ if (createProjectOptions.action === "create") {
185
+ show('project-details');
186
+ } else if (createProjectOptions.action === "clone") {
187
+ show('clone-project');
188
+ } else if (createProjectOptions.action === "open") {
189
+ show('create',{screen:'open'})
190
+ }
191
+ }
192
+ }
193
+ ]
194
+ };
195
+ })(),
196
+ 'project-details': (function() {
197
+ var projectNameInput;
198
+ var projectSummaryInput;
199
+ return {
200
+ content: function(options) {
201
+ var projectList = null;
202
+ var projectNameValid;
203
+
204
+ var pendingFormValidation = false;
205
+ $.getJSON("projects", function(data) {
206
+ projectList = {};
207
+ data.projects.forEach(function(p) {
208
+ projectList[p] = true;
209
+ if (pendingFormValidation) {
210
+ pendingFormValidation = false;
211
+ validateForm();
212
+ }
213
+ })
214
+ });
215
+ var container = $('<div class="projects-dialog-screen-start"></div>');
216
+ migrateProjectHeader.appendTo(container);
217
+ var body = $('<div class="projects-dialog-screen-start-body"></div>').appendTo(container);
218
+
219
+ $('<p>').text(RED._("projects.project-details.create")).appendTo(body);
220
+ $('<p>').text(RED._("projects.project-details.desc0")).appendTo(body);
221
+ $('<p>').text(RED._("projects.project-details.desc1")).appendTo(body);
222
+ $('<p>').text(RED._("projects.project-details.desc2")).appendTo(body);
223
+
224
+ var validateForm = function() {
225
+ var projectName = projectNameInput.val();
226
+ var valid = true;
227
+ if (projectNameInputChanged) {
228
+ if (projectList === null) {
229
+ pendingFormValidation = true;
230
+ return;
231
+ }
232
+ projectNameStatus.empty();
233
+ if (!/^[a-zA-Z0-9\-_]+$/.test(projectName) || projectList[projectName]) {
234
+ projectNameInput.addClass("input-error");
235
+ $('<i style="margin-top: 8px;" class="fa fa-exclamation-triangle"></i>').appendTo(projectNameStatus);
236
+ projectNameValid = false;
237
+ valid = false;
238
+ if (projectList[projectName]) {
239
+ projectNameSublabel.text(RED._("projects.project-details.already-exists"));
240
+ } else {
241
+ projectNameSublabel.text(RED._("projects.project-details.must-contain"));
242
+ }
243
+ } else {
244
+ projectNameInput.removeClass("input-error");
245
+ $('<i style="margin-top: 8px;" class="fa fa-check"></i>').appendTo(projectNameStatus);
246
+ projectNameSublabel.text(RED._("projects.project-details.must-contain"));
247
+ projectNameValid = true;
248
+ }
249
+ projectNameLastChecked = projectName;
250
+ }
251
+ valid = projectNameValid;
252
+ $("#projects-dialog-create-name").prop('disabled',!valid).toggleClass('disabled ui-button-disabled ui-state-disabled',!valid);
253
+ }
254
+
255
+ var row = $('<div class="form-row"></div>').appendTo(body);
256
+ $('<label for="projects-dialog-screen-create-project-name">'+RED._("projects.project-details.project-name")+'</label>').appendTo(row);
257
+
258
+ var subrow = $('<div style="position:relative;"></div>').appendTo(row);
259
+ projectNameInput = $('<input id="projects-dialog-screen-create-project-name" type="text"></input>').val(createProjectOptions.name||"").appendTo(subrow);
260
+ var projectNameStatus = $('<div class="projects-dialog-screen-input-status"></div>').appendTo(subrow);
261
+
262
+ var projectNameInputChanged = false;
263
+ var projectNameLastChecked = "";
264
+ var projectNameValid;
265
+ var checkProjectName;
266
+ var autoInsertedName = "";
267
+
268
+
269
+ projectNameInput.on("change keyup paste",function() {
270
+ projectNameInputChanged = (projectNameInput.val() !== projectNameLastChecked);
271
+ if (checkProjectName) {
272
+ clearTimeout(checkProjectName);
273
+ } else if (projectNameInputChanged) {
274
+ projectNameStatus.empty();
275
+ $('<img src="red/images/spin.svg"/>').appendTo(projectNameStatus);
276
+ if (projectNameInput.val() === '') {
277
+ validateForm();
278
+ return;
279
+ }
280
+ }
281
+ checkProjectName = setTimeout(function() {
282
+ validateForm();
283
+ checkProjectName = null;
284
+ },300)
285
+ });
286
+ projectNameSublabel = $('<label class="projects-edit-form-sublabel"><small>'+RED._("projects.project-details.must-contain")+'</small></label>').appendTo(row).find("small");
287
+
288
+ // Empty Project
289
+ row = $('<div class="form-row projects-dialog-screen-create-row projects-dialog-screen-create-row-empty"></div>').appendTo(body);
290
+ $('<label for="projects-dialog-screen-create-project-desc">'+RED._("projects.project-details.desc")+'</label>').appendTo(row);
291
+ projectSummaryInput = $('<input id="projects-dialog-screen-create-project-desc" type="text">').val(createProjectOptions.summary||"").appendTo(row);
292
+ $('<label class="projects-edit-form-sublabel"><small>'+RED._("projects.project-details.opt")+'</small></label>').appendTo(row);
293
+
294
+ setTimeout(function() {
295
+ projectNameInput.focus();
296
+ projectNameInput.change();
297
+ },50);
298
+ return container;
299
+ },
300
+ buttons: function(options) {
301
+ return [
302
+ {
303
+ text: RED._("common.label.back"),
304
+ click: function() {
305
+ show('git-config');
306
+ }
307
+ },
308
+ {
309
+ id: "projects-dialog-create-name",
310
+ disabled: true,
311
+ text: RED._("common.label.next"),
312
+ class: "primary disabled",
313
+ click: function() {
314
+ createProjectOptions.name = projectNameInput.val();
315
+ createProjectOptions.summary = projectSummaryInput.val();
316
+ show('default-files', options);
317
+ }
318
+ }
319
+ ]
320
+ }
321
+ };
322
+ })(),
323
+ 'clone-project': (function() {
324
+ var projectNameInput;
325
+ var projectSummaryInput;
326
+ var projectFlowFileInput;
327
+ var projectSecretInput;
328
+ var projectSecretSelect;
329
+ var copyProject;
330
+ var projectRepoInput;
331
+ var projectCloneSecret;
332
+ var emptyProjectCredentialInput;
333
+ var projectRepoUserInput;
334
+ var projectRepoPasswordInput;
335
+ var projectNameSublabel;
336
+ var projectRepoSSHKeySelect;
337
+ var projectRepoPassphrase;
338
+ var projectRepoRemoteName
339
+ var projectRepoBranch;
340
+ var selectedProject;
341
+
342
+ return {
343
+ content: function(options) {
344
+ var container = $('<div class="projects-dialog-screen-start"></div>');
345
+ migrateProjectHeader.appendTo(container);
346
+ var body = $('<div class="projects-dialog-screen-start-body"></div>').appendTo(container);
347
+ $('<p>').text(RED._("projects.clone-project.clone")).appendTo(body);
348
+ $('<p>').text(RED._("projects.clone-project.desc0")).appendTo(body);
349
+
350
+ var projectList = null;
351
+ var pendingFormValidation = false;
352
+ $.getJSON("projects", function(data) {
353
+ projectList = {};
354
+ data.projects.forEach(function(p) {
355
+ projectList[p] = true;
356
+ if (pendingFormValidation) {
357
+ pendingFormValidation = false;
358
+ validateForm();
359
+ }
360
+ })
361
+ });
362
+
363
+
364
+ var validateForm = function() {
365
+ var projectName = projectNameInput.val();
366
+ var valid = true;
367
+ if (projectNameInputChanged) {
368
+ if (projectList === null) {
369
+ pendingFormValidation = true;
370
+ return;
371
+ }
372
+ projectNameStatus.empty();
373
+ if (!/^[a-zA-Z0-9\-_]+$/.test(projectName) || projectList[projectName]) {
374
+ projectNameInput.addClass("input-error");
375
+ $('<i style="margin-top: 8px;" class="fa fa-exclamation-triangle"></i>').appendTo(projectNameStatus);
376
+ projectNameValid = false;
377
+ valid = false;
378
+ if (projectList[projectName]) {
379
+ projectNameSublabel.text(RED._("projects.clone-project.already-exists"));
380
+ } else {
381
+ projectNameSublabel.text(RED._("projects.clone-project.must-contain"));
382
+ }
383
+ } else {
384
+ projectNameInput.removeClass("input-error");
385
+ $('<i style="margin-top: 8px;" class="fa fa-check"></i>').appendTo(projectNameStatus);
386
+ projectNameSublabel.text(RED._("projects.clone-project.must-contain"));
387
+ projectNameValid = true;
388
+ }
389
+ projectNameLastChecked = projectName;
390
+ }
391
+ valid = projectNameValid;
392
+
393
+ var repo = projectRepoInput.val();
394
+
395
+ // var validRepo = /^(?:file|git|ssh|https?|[\d\w\.\-_]+@[\w\.]+):(?:\/\/)?[\w\.@:\/~_-]+(?:\/?|\#[\d\w\.\-_]+?)$/.test(repo);
396
+ var validRepo = repo.length > 0 && !/\s/.test(repo);
397
+ if (/^https?:\/\/[^/]+@/i.test(repo)) {
398
+ $("#projects-dialog-screen-create-project-repo-label small").text(RED._("projects.clone-project.no-info-in-url"));
399
+ validRepo = false;
400
+ }
401
+ if (!validRepo) {
402
+ if (projectRepoChanged) {
403
+ projectRepoInput.addClass("input-error");
404
+ }
405
+ valid = false;
406
+ } else {
407
+ projectRepoInput.removeClass("input-error");
408
+ }
409
+ if (/^https?:\/\//.test(repo)) {
410
+ $(".projects-dialog-screen-create-row-creds").show();
411
+ $(".projects-dialog-screen-create-row-sshkey").hide();
412
+ } else if (/^(?:ssh|[\S]+?@[\S]+?):(?:\/\/)?/.test(repo)) {
413
+ $(".projects-dialog-screen-create-row-creds").hide();
414
+ $(".projects-dialog-screen-create-row-sshkey").show();
415
+ // if ( !getSelectedSSHKey(projectRepoSSHKeySelect) ) {
416
+ // valid = false;
417
+ // }
418
+ } else {
419
+ $(".projects-dialog-screen-create-row-creds").hide();
420
+ $(".projects-dialog-screen-create-row-sshkey").hide();
421
+ }
422
+
423
+ $("#projects-dialog-clone-project").prop('disabled',!valid).toggleClass('disabled ui-button-disabled ui-state-disabled',!valid);
424
+ }
425
+
426
+ var row;
427
+
428
+ row = $('<div class="form-row projects-dialog-screen-create-row projects-dialog-screen-create-row-empty projects-dialog-screen-create-row-clone"></div>').appendTo(body);
429
+ $('<label for="projects-dialog-screen-create-project-name">'+RED._("projects.clone-project.project-name")+'</label>').appendTo(row);
430
+
431
+ var subrow = $('<div style="position:relative;"></div>').appendTo(row);
432
+ projectNameInput = $('<input id="projects-dialog-screen-create-project-name" type="text"></input>').appendTo(subrow);
433
+ var projectNameStatus = $('<div class="projects-dialog-screen-input-status"></div>').appendTo(subrow);
434
+
435
+ var projectNameInputChanged = false;
436
+ var projectNameLastChecked = "";
437
+ var projectNameValid;
438
+ var checkProjectName;
439
+ var autoInsertedName = "";
440
+
441
+
442
+ projectNameInput.on("change keyup paste",function() {
443
+ projectNameInputChanged = (projectNameInput.val() !== projectNameLastChecked);
444
+ if (checkProjectName) {
445
+ clearTimeout(checkProjectName);
446
+ } else if (projectNameInputChanged) {
447
+ projectNameStatus.empty();
448
+ $('<img src="red/images/spin.svg"/>').appendTo(projectNameStatus);
449
+ if (projectNameInput.val() === '') {
450
+ validateForm();
451
+ return;
452
+ }
453
+ }
454
+ checkProjectName = setTimeout(function() {
455
+ validateForm();
456
+ checkProjectName = null;
457
+ },300)
458
+ });
459
+ projectNameSublabel = $('<label class="projects-edit-form-sublabel"><small>'+RED._("projects.clone-project.must-contain")+'</small></label>').appendTo(row).find("small");
460
+
461
+ row = $('<div class="form-row projects-dialog-screen-create-row projects-dialog-screen-create-row-clone"></div>').appendTo(body);
462
+ $('<label for="projects-dialog-screen-create-project-repo">'+RED._("projects.clone-project.git-url")+'</label>').appendTo(row);
463
+ projectRepoInput = $('<input id="projects-dialog-screen-create-project-repo" type="text" placeholder="https://git.example.com/path/my-project.git"></input>').appendTo(row);
464
+ $('<label id="projects-dialog-screen-create-project-repo-label" class="projects-edit-form-sublabel"><small>'+RED._("projects.clone-project.protocols")+'</small></label>').appendTo(row);
465
+ var projectRepoChanged = false;
466
+ var lastProjectRepo = "";
467
+ projectRepoInput.on("change keyup paste",function() {
468
+ projectRepoChanged = true;
469
+ var repo = $(this).val();
470
+ if (lastProjectRepo !== repo) {
471
+ $("#projects-dialog-screen-create-project-repo-label small").text(RED._("projects.clone-project.protocols"));
472
+ }
473
+ lastProjectRepo = repo;
474
+
475
+ var m = /\/([^/]+?)(?:\.git)?$/.exec(repo);
476
+ if (m) {
477
+ var projectName = projectNameInput.val();
478
+ if (projectName === "" || projectName === autoInsertedName) {
479
+ autoInsertedName = m[1];
480
+ projectNameInput.val(autoInsertedName);
481
+ projectNameInput.change();
482
+ }
483
+ }
484
+ validateForm();
485
+ });
486
+
487
+ var cloneAuthRows = $('<div class="projects-dialog-screen-create-row"></div>').appendTo(body);
488
+ row = $('<div class="form-row projects-dialog-screen-create-row-auth-error"></div>').hide().appendTo(cloneAuthRows);
489
+ $('<div><i class="fa fa-warning"></i> '+RED._("projects.clone-project.auth-failed")+'</div>').appendTo(row);
490
+
491
+ // Repo credentials - username/password ----------------
492
+ row = $('<div class="hide form-row projects-dialog-screen-create-row-creds"></div>').hide().appendTo(cloneAuthRows);
493
+
494
+ var subrow = $('<div style="width: calc(50% - 10px); display:inline-block;"></div>').appendTo(row);
495
+ $('<label for="projects-dialog-screen-create-project-repo-user">'+RED._("projects.clone-project.username")+'</label>').appendTo(subrow);
496
+ projectRepoUserInput = $('<input id="projects-dialog-screen-create-project-repo-user" type="text"></input>').appendTo(subrow);
497
+
498
+ subrow = $('<div style="width: calc(50% - 10px); margin-left: 20px; display:inline-block;"></div>').appendTo(row);
499
+ $('<label for="projects-dialog-screen-create-project-repo-pass">'+RED._("projects.clone-project.passwd")+'</label>').appendTo(subrow);
500
+ projectRepoPasswordInput = $('<input id="projects-dialog-screen-create-project-repo-pass" type="password"></input>').appendTo(subrow);
501
+ // -----------------------------------------------------
502
+
503
+ // Repo credentials - key/passphrase -------------------
504
+ row = $('<div class="form-row projects-dialog-screen-create-row projects-dialog-screen-create-row-sshkey"></div>').hide().appendTo(cloneAuthRows);
505
+ subrow = $('<div style="width: calc(50% - 10px); display:inline-block;"></div>').appendTo(row);
506
+ $('<label for="projects-dialog-screen-create-project-repo-passphrase">'+RED._("projects.clone-project.ssh-key")+'</label>').appendTo(subrow);
507
+ projectRepoSSHKeySelect = $("<select>",{style:"width: 100%"}).appendTo(subrow);
508
+
509
+ $.getJSON("settings/user/keys", function(data) {
510
+ var count = 0;
511
+ data.keys.forEach(function(key) {
512
+ projectRepoSSHKeySelect.append($("<option></option>").val(key.name).text(key.name));
513
+ count++;
514
+ });
515
+ if (count === 0) {
516
+ projectRepoSSHKeySelect.addClass("input-error");
517
+ projectRepoSSHKeySelect.attr("disabled",true);
518
+ sshwarningRow.show();
519
+ } else {
520
+ projectRepoSSHKeySelect.removeClass("input-error");
521
+ projectRepoSSHKeySelect.attr("disabled",false);
522
+ sshwarningRow.hide();
523
+ }
524
+ });
525
+ subrow = $('<div style="width: calc(50% - 10px); margin-left: 20px; display:inline-block;"></div>').appendTo(row);
526
+ $('<label for="projects-dialog-screen-create-project-repo-passphrase">'+RED._("projects.clone-project.passphrase")+'</label>').appendTo(subrow);
527
+ projectRepoPassphrase = $('<input id="projects-dialog-screen-create-project-repo-passphrase" type="password"></input>').appendTo(subrow);
528
+
529
+ subrow = $('<div class="form-row projects-dialog-screen-create-row projects-dialog-screen-create-row-sshkey"></div>').appendTo(cloneAuthRows);
530
+ var sshwarningRow = $('<div class="projects-dialog-screen-create-row-auth-error-no-keys"></div>').hide().appendTo(subrow);
531
+ $('<div class="form-row"><i class="fa fa-warning"></i> '+RED._("projects.clone-project.ssh-key-desc")+'</div>').appendTo(sshwarningRow);
532
+ subrow = $('<div style="text-align: center">').appendTo(sshwarningRow);
533
+ $('<button class="editor-button">'+RED._("projects.clone-project.ssh-key-add")+'</button>').appendTo(subrow).click(function(e) {
534
+ e.preventDefault();
535
+ dialog.dialog( "close" );
536
+ RED.userSettings.show('gitconfig');
537
+ setTimeout(function() {
538
+ $("#user-settings-gitconfig-add-key").click();
539
+ },500);
540
+ });
541
+ // -----------------------------------------------------
542
+
543
+
544
+ // Secret - clone
545
+ row = $('<div class="form-row projects-dialog-screen-create-row projects-dialog-screen-create-row-clone"></div>').appendTo(body);
546
+ $('<label>'+RED._("projects.clone-project.credential-key")+'</label>').appendTo(row);
547
+ projectSecretInput = $('<input type="password"></input>').appendTo(row);
548
+
549
+
550
+
551
+ return container;
552
+ },
553
+ buttons: function(options) {
554
+ return [
555
+ {
556
+ text: RED._("common.label.back"),
557
+ click: function() {
558
+ show('git-config');
559
+ }
560
+ },
561
+ {
562
+ id: "projects-dialog-clone-project",
563
+ disabled: true,
564
+ text: RED._("common.label.clone"),
565
+ class: "primary disabled",
566
+ click: function() {
567
+ var projectType = $(".projects-dialog-screen-create-type.selected").data('type');
568
+ var projectData = {
569
+ name: projectNameInput.val(),
570
+ }
571
+ projectData.credentialSecret = projectSecretInput.val();
572
+ var repoUrl = projectRepoInput.val();
573
+ var metaData = {};
574
+ if (/^(?:ssh|[\d\w\.\-_]+@[\w\.]+):(?:\/\/)?/.test(repoUrl)) {
575
+ var selected = projectRepoSSHKeySelect.val();//false;//getSelectedSSHKey(projectRepoSSHKeySelect);
576
+ if ( selected ) {
577
+ projectData.git = {
578
+ remotes: {
579
+ 'origin': {
580
+ url: repoUrl,
581
+ keyFile: selected,
582
+ passphrase: projectRepoPassphrase.val()
583
+ }
584
+ }
585
+ };
586
+ }
587
+ else {
588
+ console.log(RED._("projects.clone-project.cant-get-ssh-key"));
589
+ return;
590
+ }
591
+ }
592
+ else {
593
+ projectData.git = {
594
+ remotes: {
595
+ 'origin': {
596
+ url: repoUrl,
597
+ username: projectRepoUserInput.val(),
598
+ password: projectRepoPasswordInput.val()
599
+ }
600
+ }
601
+ };
602
+ }
603
+
604
+ $(".projects-dialog-screen-create-row-auth-error").hide();
605
+ $("#projects-dialog-screen-create-project-repo-label small").text(RED._("projects.clone-project.protocols"));
606
+
607
+ projectRepoUserInput.removeClass("input-error");
608
+ projectRepoPasswordInput.removeClass("input-error");
609
+ projectRepoSSHKeySelect.removeClass("input-error");
610
+ projectRepoPassphrase.removeClass("input-error");
611
+
612
+ RED.deploy.setDeployInflight(true);
613
+ RED.projects.settings.switchProject(projectData.name);
614
+
615
+ sendRequest({
616
+ url: "projects",
617
+ type: "POST",
618
+ handleAuthFail: false,
619
+ responses: {
620
+ 200: function(data) {
621
+ dialog.dialog( "close" );
622
+ },
623
+ 400: {
624
+ 'project_exists': function(error) {
625
+ console.log(RED._("projects.clone-project.already-exists2"));
626
+ },
627
+ 'git_error': function(error) {
628
+ console.log(RED._("projects.clone-project.git-error"),error);
629
+ },
630
+ 'git_connection_failed': function(error) {
631
+ projectRepoInput.addClass("input-error");
632
+ $("#projects-dialog-screen-create-project-repo-label small").text(RED._("projects.clone-project.connection-failed"));
633
+ },
634
+ 'git_not_a_repository': function(error) {
635
+ projectRepoInput.addClass("input-error");
636
+ $("#projects-dialog-screen-create-project-repo-label small").text(RED._("projects.clone-project.not-git-repo"));
637
+ },
638
+ 'git_repository_not_found': function(error) {
639
+ projectRepoInput.addClass("input-error");
640
+ $("#projects-dialog-screen-create-project-repo-label small").text(RED._("projects.clone-project.repo-not-found"));
641
+ },
642
+ 'git_auth_failed': function(error) {
643
+ $(".projects-dialog-screen-create-row-auth-error").show();
644
+
645
+ projectRepoUserInput.addClass("input-error");
646
+ projectRepoPasswordInput.addClass("input-error");
647
+ // getRepoAuthDetails(req);
648
+ projectRepoSSHKeySelect.addClass("input-error");
649
+ projectRepoPassphrase.addClass("input-error");
650
+ },
651
+ 'missing_flow_file': function(error) {
652
+ // This is handled via a runtime notification.
653
+ dialog.dialog("close");
654
+ },
655
+ 'missing_package_file': function(error) {
656
+ // This is handled via a runtime notification.
657
+ dialog.dialog("close");
658
+ },
659
+ 'project_empty': function(error) {
660
+ // This is handled via a runtime notification.
661
+ dialog.dialog("close");
662
+ },
663
+ 'credentials_load_failed': function(error) {
664
+ // This is handled via a runtime notification.
665
+ dialog.dialog("close");
666
+ },
667
+ '*': function(error) {
668
+ reportUnexpectedError(error);
669
+ $( dialog ).dialog( "close" );
670
+ }
671
+ }
672
+ }
673
+ },projectData).then(function() {
674
+ RED.events.emit("project:change", {name:name});
675
+ }).always(function() {
676
+ setTimeout(function() {
677
+ RED.deploy.setDeployInflight(false);
678
+ },500);
679
+ })
680
+
681
+ }
682
+ }
683
+ ]
684
+ }
685
+ }
686
+ })(),
687
+ 'default-files': (function() {
688
+ var projectFlowFileInput;
689
+ var projectCredentialFileInput;
690
+ return {
691
+ content: function(options) {
692
+ var container = $('<div class="projects-dialog-screen-start"></div>');
693
+ migrateProjectHeader.appendTo(container);
694
+ var body = $('<div class="projects-dialog-screen-start-body"></div>').appendTo(container);
695
+
696
+ $('<p>').text(RED._("projects.default-files.create")).appendTo(body);
697
+ $('<p>').text(RED._("projects.default-files.desc0")).appendTo(body);
698
+ $('<p>').text(RED._("projects.default-files.desc1")).appendTo(body);
699
+ if (!options.existingProject && RED.settings.files) {
700
+ $('<p>').text(RED._("projects.default-files.desc2")).appendTo(body);
701
+ }
702
+
703
+ var validateForm = function() {
704
+ var valid = true;
705
+ var flowFile = projectFlowFileInput.val();
706
+ if (flowFile === "" || !/\.json$/.test(flowFile)) {
707
+ valid = false;
708
+ if (!projectFlowFileInput.hasClass("input-error")) {
709
+ projectFlowFileInput.addClass("input-error");
710
+ projectFlowFileInput.next().empty().append('<i style="margin-top: 8px;" class="fa fa-exclamation-triangle"></i>');
711
+ }
712
+ projectCredentialFileInput.text("");
713
+ if (!projectCredentialFileInput.hasClass("input-error")) {
714
+ projectCredentialFileInput.addClass("input-error");
715
+ projectCredentialFileInput.next().empty().append('<i style="margin-top: 8px;" class="fa fa-exclamation-triangle"></i>');
716
+ }
717
+ } else {
718
+ if (projectFlowFileInput.hasClass("input-error")) {
719
+ projectFlowFileInput.removeClass("input-error");
720
+ projectFlowFileInput.next().empty();
721
+ }
722
+ if (projectCredentialFileInput.hasClass("input-error")) {
723
+ projectCredentialFileInput.removeClass("input-error");
724
+ projectCredentialFileInput.next().empty();
725
+ }
726
+ projectCredentialFileInput.text(flowFile.substring(0,flowFile.length-5)+"_cred.json");
727
+ }
728
+ $("#projects-dialog-create-default-files").prop('disabled',!valid).toggleClass('disabled ui-button-disabled ui-state-disabled',!valid);
729
+ }
730
+ var row = $('<div class="form-row"></div>').appendTo(body);
731
+ $('<label for="projects-dialog-screen-create-project-file">'+RED._("projects.default-files.flow-file")+'</label>').appendTo(row);
732
+ var subrow = $('<div style="position:relative;"></div>').appendTo(row);
733
+ var defaultFlowFile = (createProjectOptions.files &&createProjectOptions.files.flow) || (RED.settings.files && RED.settings.files.flow)||"flow.json";
734
+ projectFlowFileInput = $('<input id="projects-dialog-screen-create-project-file" type="text">').val(defaultFlowFile)
735
+ .on("change keyup paste",validateForm)
736
+ .appendTo(subrow);
737
+ $('<div class="projects-dialog-screen-input-status"></div>').appendTo(subrow);
738
+ $('<label class="projects-edit-form-sublabel"><small>*.json</small></label>').appendTo(row);
739
+
740
+ var defaultCredentialsFile = (createProjectOptions.files &&createProjectOptions.files.credentials) || (RED.settings.files && RED.settings.files.credentials)||"flow_cred.json";
741
+ row = $('<div class="form-row"></div>').appendTo(body);
742
+ $('<label for="projects-dialog-screen-create-project-credfile">'+RED._("projects.default-files.credentials-file")+'</label>').appendTo(row);
743
+ subrow = $('<div style="position:relative;"></div>').appendTo(row);
744
+ projectCredentialFileInput = $('<div style="width: 100%" class="uneditable-input" id="projects-dialog-screen-create-project-credentials">').text(defaultCredentialsFile)
745
+ .appendTo(subrow);
746
+ $('<div class="projects-dialog-screen-input-status"></div>').appendTo(subrow);
747
+
748
+ setTimeout(function() {
749
+ projectFlowFileInput.focus();
750
+ validateForm();
751
+ },50);
752
+
753
+ return container;
754
+ },
755
+ buttons: function(options) {
756
+ return [
757
+ {
758
+ // id: "clipboard-dialog-cancel",
759
+ text: RED._(options.existingProject ? "common.label.cancel": "common.label.back"),
760
+ click: function() {
761
+ if (options.existingProject) {
762
+ $(this).dialog('close');
763
+ } else {
764
+ show('project-details',options);
765
+ }
766
+ }
767
+ },
768
+ {
769
+ id: "projects-dialog-create-default-files",
770
+ text: RED._("common.label.next"),
771
+ class: "primary",
772
+ click: function() {
773
+ createProjectOptions.files = {
774
+ flow: projectFlowFileInput.val(),
775
+ credentials: projectCredentialFileInput.text()
776
+ }
777
+ if (!options.existingProject) {
778
+ createProjectOptions.migrateFiles = true;
779
+ }
780
+ show('encryption-config',options);
781
+ }
782
+ }
783
+ ]
784
+ }
785
+ }
786
+ })(),
787
+ 'encryption-config': (function() {
788
+ var emptyProjectCredentialInput;
789
+ return {
790
+ content: function(options) {
791
+
792
+ var container = $('<div class="projects-dialog-screen-start"></div>');
793
+ migrateProjectHeader.appendTo(container);
794
+ var body = $('<div class="projects-dialog-screen-start-body"></div>').appendTo(container);
795
+
796
+ $('<p>').text(RED._("projects.encryption-config.setup")).appendTo(body);
797
+ if (options.existingProject) {
798
+ $('<p>').text(RED._("projects.encryption-config.desc0")).appendTo(body);
799
+ $('<p>').text(RED._("projects.encryption-config.desc1")).appendTo(body);
800
+ } else {
801
+ if (RED.settings.flowEncryptionType === 'disabled') {
802
+ $('<p>').text(RED._("projects.encryption-config.desc2")).appendTo(body);
803
+ $('<p>').text(RED._("projects.encryption-config.desc3")).appendTo(body);
804
+ $('<p>').text(RED._("projects.encryption-config.desc4")).appendTo(body);
805
+ } else {
806
+ if (RED.settings.flowEncryptionType === 'user') {
807
+ $('<p>').text(RED._("projects.encryption-config.desc5")).appendTo(body);
808
+ } else if (RED.settings.flowEncryptionType === 'system') {
809
+ $('<p>').text(RED._("projects.encryption-config.desc6")).appendTo(body);
810
+ }
811
+ $('<p>').text(RED._("projects.encryption-config.desc7")).appendTo(body);
812
+ }
813
+ }
814
+
815
+ // var row = $('<div class="form-row"></div>').appendTo(body);
816
+ // $('<label for="">Username</label>').appendTo(row);
817
+ // var gitUsernameInput = $('<input type="text">').val(currentGitSettings.user.name||"").appendTo(row);
818
+ // // $('<div style="position:relative;"></div>').text("This does not need to be your real name").appendTo(row);
819
+ //
820
+ // row = $('<div class="form-row"></div>').appendTo(body);
821
+ // $('<label for="">Email</label>').appendTo(row);
822
+ // var gitEmailInput = $('<input type="text">').val(currentGitSettings.user.email||"").appendTo(row);
823
+ // // $('<div style="position:relative;"></div>').text("Something something email").appendTo(row);
824
+
825
+ var validateForm = function() {
826
+ var valid = true;
827
+ var encryptionState = $("input[name=projects-encryption-type]:checked").val();
828
+ if (encryptionState === 'enabled') {
829
+ var encryptionKeyType = $("input[name=projects-encryption-key]:checked").val();
830
+ if (encryptionKeyType === 'custom') {
831
+ valid = valid && emptyProjectCredentialInput.val()!=='';
832
+ }
833
+ }
834
+ $("#projects-dialog-create-encryption").prop('disabled',!valid).toggleClass('disabled ui-button-disabled ui-state-disabled',!valid);
835
+ }
836
+
837
+
838
+ var row = $('<div class="form-row projects-dialog-screen-create-row projects-dialog-screen-create-row-empty"></div>').appendTo(body);
839
+ $('<label>'+RED._("projects.encryption-config.credentials")+'</label>').appendTo(row);
840
+
841
+ var credentialsBox = $('<div style="width: 550px">').appendTo(row);
842
+ var credentialsRightBox = $('<div style="min-height:150px; box-sizing: border-box; float: right; vertical-align: top; width: 331px; margin-left: -1px; padding: 15px; margin-top: -15px; border: 1px solid #ccc; border-radius: 3px; display: inline-block">').appendTo(credentialsBox);
843
+ var credentialsLeftBox = $('<div style="vertical-align: top; width: 220px; display: inline-block">').appendTo(credentialsBox);
844
+
845
+ var credentialsEnabledBox = $('<div class="form-row" style="padding: 7px 8px 3px 8px;border: 1px solid #ccc;border-radius: 4px;border-top-right-radius: 0;border-bottom-right-radius: 0;border-right-color: white;"></div>').appendTo(credentialsLeftBox);
846
+ $('<label class="projects-edit-form-inline-label" style="margin-left: 5px"><input type="radio" style="vertical-align: middle; margin-top:0; margin-right: 10px;" name="projects-encryption-type" value="enabled"> <i style="font-size: 1.4em; margin-right: 8px; vertical-align: middle; color: #888;" class="fa fa-lock"></i> <span style="vertical-align: middle;">'+RED._("projects.encryption-config.enable")+'</span></label>').appendTo(credentialsEnabledBox);
847
+ var credentialsDisabledBox = $('<div class="form-row" style="padding: 7px 8px 3px 8px;border: 1px solid white;border-radius: 4px;border-top-right-radius: 0;border-bottom-right-radius: 0;border-right-color: #ccc; "></div>').appendTo(credentialsLeftBox);
848
+ $('<label class="projects-edit-form-inline-label" style="margin-left: 5px"><input type="radio" style="vertical-align: middle; margin-top:0; margin-right: 10px;" name="projects-encryption-type" value="disabled"> <i style="font-size: 1.4em; margin-right: 8px; vertical-align: middle; color: #888;" class="fa fa-unlock"></i> <span style="vertical-align: middle;">'+RED._("projects.encryption-config.disable")+'</span></label>').appendTo(credentialsDisabledBox);
849
+
850
+ credentialsLeftBox.find("input[name=projects-encryption-type]").click(function(e) {
851
+ var val = $(this).val();
852
+ var toEnable;
853
+ var toDisable;
854
+ if (val === 'enabled') {
855
+ toEnable = credentialsEnabledBox;
856
+ toDisable = credentialsDisabledBox;
857
+ $(".projects-encryption-enabled-row").show();
858
+ $(".projects-encryption-disabled-row").hide();
859
+ if ($("input[name=projects-encryption-key]:checked").val() === 'custom') {
860
+ emptyProjectCredentialInput.focus();
861
+ }
862
+
863
+ } else {
864
+ toDisable = credentialsEnabledBox;
865
+ toEnable = credentialsDisabledBox;
866
+ $(".projects-encryption-enabled-row").hide();
867
+ $(".projects-encryption-disabled-row").show();
868
+ }
869
+
870
+ toEnable.css({
871
+ borderColor: "#ccc",
872
+ borderRightColor: "white"
873
+ });
874
+ toDisable.css({
875
+ borderColor: "white",
876
+ borderRightColor: "#ccc"
877
+ });
878
+
879
+ validateForm();
880
+ })
881
+
882
+ row = $('<div class="form-row projects-encryption-enabled-row"></div>').appendTo(credentialsRightBox);
883
+ $('<label class="projects-edit-form-inline-label '+((RED.settings.flowEncryptionType !== 'user')?'disabled':'')+'" style="margin-left: 5px"><input '+((RED.settings.flowEncryptionType !== 'user')?RED._("projects.encryption-config.disabled"):'')+' type="radio" style="vertical-align: middle; margin-top:0; margin-right: 10px;" value="default" name="projects-encryption-key"> <span style="vertical-align: middle;">'+RED._("projects.encryption-config.copy")+'</span></label>').appendTo(row);
884
+ row = $('<div class="form-row projects-encryption-enabled-row"></div>').appendTo(credentialsRightBox);
885
+ $('<label class="projects-edit-form-inline-label" style="margin-left: 5px"><input type="radio" style="vertical-align: middle; margin-top:0; margin-right: 10px;" value="custom" name="projects-encryption-key"> <span style="vertical-align: middle;">'+RED._("projects.encryption-config.use-custom")+'</span></label>').appendTo(row);
886
+ row = $('<div class="projects-encryption-enabled-row"></div>').appendTo(credentialsRightBox);
887
+ emptyProjectCredentialInput = $('<input disabled type="password" style="margin-left: 25px; width: calc(100% - 30px);"></input>').appendTo(row);
888
+ emptyProjectCredentialInput.on("change keyup paste", validateForm);
889
+
890
+ row = $('<div class="form-row projects-encryption-disabled-row"></div>').hide().appendTo(credentialsRightBox);
891
+ $('<div class="" style="padding: 5px 20px;"><i class="fa fa-warning"></i> '+RED._("projects.encryption-config.desc8")+'</div>').appendTo(row);
892
+
893
+ credentialsRightBox.find("input[name=projects-encryption-key]").click(function() {
894
+ var val = $(this).val();
895
+ emptyProjectCredentialInput.attr("disabled",val === 'default');
896
+ if (val === "custom") {
897
+ emptyProjectCredentialInput.focus();
898
+ }
899
+ validateForm();
900
+ });
901
+
902
+ setTimeout(function() {
903
+ credentialsLeftBox.find("input[name=projects-encryption-type][value=enabled]").click();
904
+ if (RED.settings.flowEncryptionType !== 'user') {
905
+ credentialsRightBox.find("input[name=projects-encryption-key][value=custom]").click();
906
+ } else {
907
+ credentialsRightBox.find("input[name=projects-encryption-key][value=default]").click();
908
+ }
909
+ validateForm();
910
+ },100);
911
+
912
+ return container;
913
+ },
914
+ buttons: function(options) {
915
+ return [
916
+ {
917
+ // id: "clipboard-dialog-cancel",
918
+ text: RED._("common.label.back"),
919
+ click: function() {
920
+ show('default-files',options);
921
+ }
922
+ },
923
+ {
924
+ id: "projects-dialog-create-encryption",
925
+ text: RED._(options.existingProject?"projects.encryption-config.create-project-files":"projects.encryption-config.create-project"),
926
+ class: "primary disabled",
927
+ disabled: true,
928
+ click: function() {
929
+ var encryptionState = $("input[name=projects-encryption-type]:checked").val();
930
+ if (encryptionState === 'enabled') {
931
+ var encryptionKeyType = $("input[name=projects-encryption-key]:checked").val();
932
+ if (encryptionKeyType === 'custom') {
933
+ createProjectOptions.credentialSecret = emptyProjectCredentialInput.val();
934
+ } else {
935
+ // If 'use existing', leave createProjectOptions.credentialSecret blank
936
+ // - that will trigger it to use the existing key
937
+ // TODO: this option should be disabled if encryption is disabled
938
+ }
939
+ } else {
940
+ // Disabled encryption by explicitly setting credSec to false
941
+ createProjectOptions.credentialSecret = false;
942
+ }
943
+ RED.deploy.setDeployInflight(true);
944
+ RED.projects.settings.switchProject(createProjectOptions.name);
945
+
946
+ var method = "POST";
947
+ var url = "projects";
948
+
949
+ if (options.existingProject) {
950
+ createProjectOptions.initialise = true;
951
+ method = "PUT";
952
+ url = "projects/"+activeProject.name;
953
+ }
954
+ var self = this;
955
+ sendRequest({
956
+ url: url,
957
+ type: method,
958
+ requireCleanWorkspace: true,
959
+ handleAuthFail: false,
960
+ responses: {
961
+ 200: function(data) {
962
+ createProjectOptions = {};
963
+ if (options.existingProject) {
964
+ $( self ).dialog( "close" );
965
+ } else {
966
+ show('create-success');
967
+ RED.menu.setDisabled('menu-item-projects-open',false);
968
+ RED.menu.setDisabled('menu-item-projects-settings',false);
969
+ }
970
+ },
971
+ 400: {
972
+ 'project_exists': function(error) {
973
+ console.log(RED._("projects.encryption-config.already-exists"));
974
+ },
975
+ 'git_error': function(error) {
976
+ console.log(RED._("projects.encryption-config.git-error"),error);
977
+ },
978
+ 'git_connection_failed': function(error) {
979
+ projectRepoInput.addClass("input-error");
980
+ },
981
+ 'git_auth_failed': function(error) {
982
+ projectRepoUserInput.addClass("input-error");
983
+ projectRepoPasswordInput.addClass("input-error");
984
+ // getRepoAuthDetails(req);
985
+ console.log(RED._("projects.encryption-config.git-auth-error"),error);
986
+ },
987
+ '*': function(error) {
988
+ reportUnexpectedError(error);
989
+ $( dialog ).dialog( "close" );
990
+ }
991
+ }
992
+ }
993
+ },createProjectOptions).always(function() {
994
+ setTimeout(function() {
995
+ RED.deploy.setDeployInflight(false);
996
+ },500);
997
+ })
998
+ }
999
+ }
1000
+ ];
1001
+ }
1002
+ }
1003
+ })(),
1004
+ 'create-success': {
1005
+ content: function(options) {
1006
+
1007
+ var container = $('<div class="projects-dialog-screen-start"></div>');
1008
+ migrateProjectHeader.appendTo(container);
1009
+ var body = $('<div class="projects-dialog-screen-start-body"></div>').appendTo(container);
1010
+
1011
+ $('<p>').text(RED._("projects.create-success.success")).appendTo(body);
1012
+ $('<p>').text(RED._("projects.create-success.desc0")).appendTo(body);
1013
+ $('<p>').text(RED._("projects.create-success.desc1")).appendTo(body);
1014
+ $('<p>').text(RED._("projects.create-success.desc2")).appendTo(body);
1015
+
1016
+ return container;
1017
+ },
1018
+ buttons: [
1019
+ {
1020
+ text: RED._("common.label.done"),
1021
+ click: function() {
1022
+ $( this ).dialog( "close" );
1023
+ }
1024
+ }
1025
+ ]
1026
+ },
1027
+ 'create': (function() {
1028
+ var projectNameInput;
1029
+ var projectSummaryInput;
1030
+ var projectFlowFileInput;
1031
+ var projectSecretInput;
1032
+ var projectSecretSelect;
1033
+ var copyProject;
1034
+ var projectRepoInput;
1035
+ var projectCloneSecret;
1036
+ var emptyProjectCredentialInput;
1037
+ var projectRepoUserInput;
1038
+ var projectRepoPasswordInput;
1039
+ var projectNameSublabel;
1040
+ var projectRepoSSHKeySelect;
1041
+ var projectRepoPassphrase;
1042
+ var projectRepoRemoteName
1043
+ var projectRepoBranch;
1044
+ var selectedProject;
1045
+
1046
+ return {
1047
+ title: RED._("projects.create.projects"),
1048
+ content: function(options) {
1049
+ var projectList = null;
1050
+ selectedProject = null;
1051
+ var pendingFormValidation = false;
1052
+ $.getJSON("projects", function(data) {
1053
+ projectList = {};
1054
+ data.projects.forEach(function(p) {
1055
+ projectList[p] = true;
1056
+ if (pendingFormValidation) {
1057
+ pendingFormValidation = false;
1058
+ validateForm();
1059
+ }
1060
+ })
1061
+ });
1062
+
1063
+ var container = $('<div class="projects-dialog-screen-create"></div>');
1064
+ var row;
1065
+
1066
+ var validateForm = function() {
1067
+ var projectName = projectNameInput.val();
1068
+ var valid = true;
1069
+ if (projectNameInputChanged) {
1070
+ if (projectList === null) {
1071
+ pendingFormValidation = true;
1072
+ return;
1073
+ }
1074
+ projectNameStatus.empty();
1075
+ if (!/^[a-zA-Z0-9\-_]+$/.test(projectName) || projectList[projectName]) {
1076
+ projectNameInput.addClass("input-error");
1077
+ $('<i style="margin-top: 8px;" class="fa fa-exclamation-triangle"></i>').appendTo(projectNameStatus);
1078
+ projectNameValid = false;
1079
+ valid = false;
1080
+ if (projectList[projectName]) {
1081
+ projectNameSublabel.text(RED._("projects.create.already-exists"));
1082
+ } else {
1083
+ projectNameSublabel.text(RED._("projects.create.must-contain"));
1084
+ }
1085
+ } else {
1086
+ projectNameInput.removeClass("input-error");
1087
+ $('<i style="margin-top: 8px;" class="fa fa-check"></i>').appendTo(projectNameStatus);
1088
+ projectNameSublabel.text(RED._("projects.create.must-contain"));
1089
+ projectNameValid = true;
1090
+ }
1091
+ projectNameLastChecked = projectName;
1092
+ }
1093
+ valid = projectNameValid;
1094
+
1095
+ var projectType = $(".projects-dialog-screen-create-type.selected").data('type');
1096
+ if (projectType === 'copy') {
1097
+ if (!copyProject) {
1098
+ valid = false;
1099
+ }
1100
+ } else if (projectType === 'clone') {
1101
+ var repo = projectRepoInput.val();
1102
+
1103
+ // var validRepo = /^(?:file|git|ssh|https?|[\d\w\.\-_]+@[\w\.]+):(?:\/\/)?[\w\.@:\/~_-]+(?:\/?|\#[\d\w\.\-_]+?)$/.test(repo);
1104
+ var validRepo = repo.length > 0 && !/\s/.test(repo);
1105
+ if (/^https?:\/\/[^/]+@/i.test(repo)) {
1106
+ $("#projects-dialog-screen-create-project-repo-label small").text(RED._("projects.create.no-info-in-url"));
1107
+ validRepo = false;
1108
+ }
1109
+ if (!validRepo) {
1110
+ if (projectRepoChanged) {
1111
+ projectRepoInput.addClass("input-error");
1112
+ }
1113
+ valid = false;
1114
+ } else {
1115
+ projectRepoInput.removeClass("input-error");
1116
+ }
1117
+ if (/^https?:\/\//.test(repo)) {
1118
+ $(".projects-dialog-screen-create-row-creds").show();
1119
+ $(".projects-dialog-screen-create-row-sshkey").hide();
1120
+ } else if (/^(?:ssh|[\S]+?@[\S]+?):(?:\/\/)?/.test(repo)) {
1121
+ $(".projects-dialog-screen-create-row-creds").hide();
1122
+ $(".projects-dialog-screen-create-row-sshkey").show();
1123
+ // if ( !getSelectedSSHKey(projectRepoSSHKeySelect) ) {
1124
+ // valid = false;
1125
+ // }
1126
+ } else {
1127
+ $(".projects-dialog-screen-create-row-creds").hide();
1128
+ $(".projects-dialog-screen-create-row-sshkey").hide();
1129
+ }
1130
+
1131
+
1132
+ } else if (projectType === 'empty') {
1133
+ var flowFile = projectFlowFileInput.val();
1134
+ if (flowFile === "" || !/\.json$/.test(flowFile)) {
1135
+ valid = false;
1136
+ if (!projectFlowFileInput.hasClass("input-error")) {
1137
+ projectFlowFileInput.addClass("input-error");
1138
+ projectFlowFileInput.next().empty().append('<i style="margin-top: 8px;" class="fa fa-exclamation-triangle"></i>');
1139
+ }
1140
+ } else {
1141
+ if (projectFlowFileInput.hasClass("input-error")) {
1142
+ projectFlowFileInput.removeClass("input-error");
1143
+ projectFlowFileInput.next().empty();
1144
+ }
1145
+ }
1146
+
1147
+ var encryptionState = $("input[name=projects-encryption-type]:checked").val();
1148
+ if (encryptionState === 'enabled') {
1149
+ var encryptionKeyType = $("input[name=projects-encryption-key]:checked").val();
1150
+ if (encryptionKeyType === 'custom') {
1151
+ valid = valid && emptyProjectCredentialInput.val()!==''
1152
+ }
1153
+ }
1154
+ } else if (projectType === 'open') {
1155
+ valid = !!selectedProject;
1156
+ }
1157
+
1158
+ $("#projects-dialog-create").prop('disabled',!valid).toggleClass('disabled ui-button-disabled ui-state-disabled',!valid);
1159
+ }
1160
+
1161
+ row = $('<div class="form-row button-group"></div>').appendTo(container);
1162
+
1163
+ var openProject = $('<button data-type="open" class="editor-button projects-dialog-screen-create-type toggle"><i class="fa fa-archive fa-2x"></i><i style="position: absolute;" class="fa fa-folder-open"></i><br/>'+RED._("projects.create.open")+'</button>').appendTo(row);
1164
+ var createAsEmpty = $('<button data-type="empty" class="editor-button projects-dialog-screen-create-type toggle"><i class="fa fa-archive fa-2x"></i><i style="position: absolute;" class="fa fa-asterisk"></i><br/>'+RED._("projects.create.create")+'</button>').appendTo(row);
1165
+ // var createAsCopy = $('<button data-type="copy" class="editor-button projects-dialog-screen-create-type toggle"><i class="fa fa-archive fa-2x"></i><i class="fa fa-long-arrow-right fa-2x"></i><i class="fa fa-archive fa-2x"></i><br/>Copy existing</button>').appendTo(row);
1166
+ var createAsClone = $('<button data-type="clone" class="editor-button projects-dialog-screen-create-type toggle"><i class="fa fa-archive fa-2x"></i><i style="position: absolute;" class="fa fa-git"></i><br/>'+RED._("projects.create.clone")+'</button>').appendTo(row);
1167
+ // var createAsClone = $('<button data-type="clone" class="editor-button projects-dialog-screen-create-type toggle"><i class="fa fa-git fa-2x"></i><i class="fa fa-arrows-h fa-2x"></i><i class="fa fa-archive fa-2x"></i><br/>Clone Repository</button>').appendTo(row);
1168
+ row.find(".projects-dialog-screen-create-type").click(function(evt) {
1169
+ evt.preventDefault();
1170
+ container.find(".projects-dialog-screen-create-type").removeClass('selected');
1171
+ $(this).addClass('selected');
1172
+ container.find(".projects-dialog-screen-create-row").hide();
1173
+ container.find(".projects-dialog-screen-create-row-"+$(this).data('type')).show();
1174
+ validateForm();
1175
+ projectNameInput.focus();
1176
+ switch ($(this).data('type')) {
1177
+ case "open": $("#projects-dialog-create").text(RED._("projects.create.open")); break;
1178
+ case "empty": $("#projects-dialog-create").text(RED._("projects.create.create")); break;
1179
+ case "clone": $("#projects-dialog-create").text(RED._("projects.create.clone")); break;
1180
+ }
1181
+ })
1182
+
1183
+ row = $('<div class="form-row projects-dialog-screen-create-row projects-dialog-screen-create-row-open"></div>').hide().appendTo(container);
1184
+ createProjectList({
1185
+ canSelectActive: false,
1186
+ dblclick: function(project) {
1187
+ selectedProject = project;
1188
+ $("#projects-dialog-create").click();
1189
+ },
1190
+ select: function(project) {
1191
+ selectedProject = project;
1192
+ validateForm();
1193
+ },
1194
+ delete: function(project) {
1195
+ if (projectList) {
1196
+ delete projectList[project.name];
1197
+ }
1198
+ selectedProject = null;
1199
+
1200
+ validateForm();
1201
+ }
1202
+ }).appendTo(row);
1203
+
1204
+ row = $('<div class="form-row projects-dialog-screen-create-row projects-dialog-screen-create-row-empty projects-dialog-screen-create-row-clone"></div>').appendTo(container);
1205
+ $('<label for="projects-dialog-screen-create-project-name">'+RED._("projects.create.project-name")+'</label>').appendTo(row);
1206
+
1207
+ var subrow = $('<div style="position:relative;"></div>').appendTo(row);
1208
+ projectNameInput = $('<input id="projects-dialog-screen-create-project-name" type="text"></input>').appendTo(subrow);
1209
+ var projectNameStatus = $('<div class="projects-dialog-screen-input-status"></div>').appendTo(subrow);
1210
+
1211
+ var projectNameInputChanged = false;
1212
+ var projectNameLastChecked = "";
1213
+ var projectNameValid;
1214
+ var checkProjectName;
1215
+ var autoInsertedName = "";
1216
+
1217
+
1218
+ projectNameInput.on("change keyup paste",function() {
1219
+ projectNameInputChanged = (projectNameInput.val() !== projectNameLastChecked);
1220
+ if (checkProjectName) {
1221
+ clearTimeout(checkProjectName);
1222
+ } else if (projectNameInputChanged) {
1223
+ projectNameStatus.empty();
1224
+ $('<img src="red/images/spin.svg"/>').appendTo(projectNameStatus);
1225
+ if (projectNameInput.val() === '') {
1226
+ validateForm();
1227
+ return;
1228
+ }
1229
+ }
1230
+ checkProjectName = setTimeout(function() {
1231
+ validateForm();
1232
+ checkProjectName = null;
1233
+ },300)
1234
+ });
1235
+ projectNameSublabel = $('<label class="projects-edit-form-sublabel"><small>'+RED._("projects.create.must-contain")+'</small></label>').appendTo(row).find("small");
1236
+
1237
+ // Empty Project
1238
+ row = $('<div class="form-row projects-dialog-screen-create-row projects-dialog-screen-create-row-empty"></div>').appendTo(container);
1239
+ $('<label for="projects-dialog-screen-create-project-desc">'+RED._("projects.create.desc")+'</label>').appendTo(row);
1240
+ projectSummaryInput = $('<input id="projects-dialog-screen-create-project-desc" type="text">').appendTo(row);
1241
+ $('<label class="projects-edit-form-sublabel"><small>'+RED._("projects.create.opt")+'</small></label>').appendTo(row);
1242
+
1243
+ row = $('<div class="form-row projects-dialog-screen-create-row projects-dialog-screen-create-row-empty"></div>').appendTo(container);
1244
+ $('<label for="projects-dialog-screen-create-project-file">'+RED._("projects.create.flow-file")+'</label>').appendTo(row);
1245
+ subrow = $('<div style="position:relative;"></div>').appendTo(row);
1246
+ projectFlowFileInput = $('<input id="projects-dialog-screen-create-project-file" type="text">').val("flow.json")
1247
+ .on("change keyup paste",validateForm)
1248
+ .appendTo(subrow);
1249
+ $('<div class="projects-dialog-screen-input-status"></div>').appendTo(subrow);
1250
+ $('<label class="projects-edit-form-sublabel"><small>*.json</small></label>').appendTo(row);
1251
+
1252
+ row = $('<div class="form-row projects-dialog-screen-create-row projects-dialog-screen-create-row-empty"></div>').appendTo(container);
1253
+ $('<label>'+RED._("projects.create.credentials")+'</label>').appendTo(row);
1254
+
1255
+ var credentialsBox = $('<div style="width: 550px">').appendTo(row);
1256
+ var credentialsRightBox = $('<div style="min-height:150px; box-sizing: border-box; float: right; vertical-align: top; width: 331px; margin-left: -1px; padding: 15px; margin-top: -15px; border: 1px solid #ccc; border-radius: 3px; display: inline-block">').appendTo(credentialsBox);
1257
+ var credentialsLeftBox = $('<div style="vertical-align: top; width: 220px; display: inline-block">').appendTo(credentialsBox);
1258
+
1259
+ var credentialsEnabledBox = $('<div class="form-row" style="padding: 7px 8px 3px 8px;border: 1px solid #ccc;border-radius: 4px;border-top-right-radius: 0;border-bottom-right-radius: 0;border-right-color: white;"></div>').appendTo(credentialsLeftBox);
1260
+ $('<label class="projects-edit-form-inline-label" style="margin-left: 5px"><input type="radio" checked style="vertical-align: middle; margin-top:0; margin-right: 10px;" name="projects-encryption-type" value="enabled"> <i style="font-size: 1.4em; margin-right: 8px; vertical-align: middle; color: #888;" class="fa fa-lock"></i> <span style="vertical-align: middle;">'+RED._("projects.create.enable-encryption")+'</span></label>').appendTo(credentialsEnabledBox);
1261
+ var credentialsDisabledBox = $('<div class="form-row" style="padding: 7px 8px 3px 8px;border: 1px solid white;border-radius: 4px;border-top-right-radius: 0;border-bottom-right-radius: 0;border-right-color: #ccc; "></div>').appendTo(credentialsLeftBox);
1262
+ $('<label class="projects-edit-form-inline-label" style="margin-left: 5px"><input type="radio" style="vertical-align: middle; margin-top:0; margin-right: 10px;" name="projects-encryption-type" value="disabled"> <i style="font-size: 1.4em; margin-right: 8px; vertical-align: middle; color: #888;" class="fa fa-unlock"></i> <span style="vertical-align: middle;">'+RED._("projects.create.disable-encryption")+'</span></label>').appendTo(credentialsDisabledBox);
1263
+
1264
+ credentialsLeftBox.find("input[name=projects-encryption-type]").click(function(e) {
1265
+ var val = $(this).val();
1266
+ var toEnable;
1267
+ var toDisable;
1268
+ if (val === 'enabled') {
1269
+ toEnable = credentialsEnabledBox;
1270
+ toDisable = credentialsDisabledBox;
1271
+ $(".projects-encryption-enabled-row").show();
1272
+ $(".projects-encryption-disabled-row").hide();
1273
+ if ($("input[name=projects-encryption-key]:checked").val() === 'custom') {
1274
+ emptyProjectCredentialInput.focus();
1275
+ }
1276
+ } else {
1277
+ toDisable = credentialsEnabledBox;
1278
+ toEnable = credentialsDisabledBox;
1279
+ $(".projects-encryption-enabled-row").hide();
1280
+ $(".projects-encryption-disabled-row").show();
1281
+
1282
+ }
1283
+
1284
+ toEnable.css({
1285
+ borderColor: "#ccc",
1286
+ borderRightColor: "white"
1287
+ });
1288
+ toDisable.css({
1289
+ borderColor: "white",
1290
+ borderRightColor: "#ccc"
1291
+ })
1292
+ validateForm();
1293
+ })
1294
+
1295
+ row = $('<div class="form-row projects-encryption-enabled-row"></div>').appendTo(credentialsRightBox);
1296
+ $('<label class="projects-edit-form-inline-label">'+RED._("projects.create.encryption-key")+'</label>').appendTo(row);
1297
+ // row = $('<div class="projects-encryption-enabled-row"></div>').appendTo(credentialsRightBox);
1298
+ emptyProjectCredentialInput = $('<input type="password"></input>').appendTo(row);
1299
+ emptyProjectCredentialInput.on("change keyup paste", validateForm);
1300
+ $('<label class="projects-edit-form-sublabel"><small>'+RED._("projects.create.desc0")+'</small></label>').appendTo(row);
1301
+
1302
+
1303
+ row = $('<div class="form-row projects-encryption-disabled-row"></div>').hide().appendTo(credentialsRightBox);
1304
+ $('<div class="" style="padding: 5px 20px;"><i class="fa fa-warning"></i> '+RED._("projects.create.desc1")+'</div>').appendTo(row);
1305
+
1306
+ credentialsRightBox.find("input[name=projects-encryption-key]").click(function() {
1307
+ var val = $(this).val();
1308
+ emptyProjectCredentialInput.attr("disabled",val === 'default');
1309
+ if (val === "custom") {
1310
+ emptyProjectCredentialInput.focus();
1311
+ }
1312
+ validateForm();
1313
+ })
1314
+
1315
+ // Clone Project
1316
+ row = $('<div class="hide form-row projects-dialog-screen-create-row projects-dialog-screen-create-row-clone"></div>').appendTo(container);
1317
+ $('<label for="projects-dialog-screen-create-project-repo">'+RED._("projects.create.git-url")+'</label>').appendTo(row);
1318
+ projectRepoInput = $('<input id="projects-dialog-screen-create-project-repo" type="text" placeholder="https://git.example.com/path/my-project.git"></input>').appendTo(row);
1319
+ $('<label id="projects-dialog-screen-create-project-repo-label" class="projects-edit-form-sublabel"><small>'+RED._("projects.create.protocols")+'</small></label>').appendTo(row);
1320
+
1321
+ var projectRepoChanged = false;
1322
+ var lastProjectRepo = "";
1323
+ projectRepoInput.on("change keyup paste",function() {
1324
+ projectRepoChanged = true;
1325
+ var repo = $(this).val();
1326
+ if (lastProjectRepo !== repo) {
1327
+ $("#projects-dialog-screen-create-project-repo-label small").text(RED._("projects.create.protocols"));
1328
+ }
1329
+ lastProjectRepo = repo;
1330
+
1331
+ var m = /\/([^/]+?)(?:\.git)?$/.exec(repo);
1332
+ if (m) {
1333
+ var projectName = projectNameInput.val();
1334
+ if (projectName === "" || projectName === autoInsertedName) {
1335
+ autoInsertedName = m[1];
1336
+ projectNameInput.val(autoInsertedName);
1337
+ projectNameInput.change();
1338
+ }
1339
+ }
1340
+ validateForm();
1341
+ });
1342
+
1343
+
1344
+ var cloneAuthRows = $('<div class="hide projects-dialog-screen-create-row projects-dialog-screen-create-row-clone"></div>').hide().appendTo(container);
1345
+ row = $('<div class="form-row projects-dialog-screen-create-row-auth-error"></div>').hide().appendTo(cloneAuthRows);
1346
+ $('<div><i class="fa fa-warning"></i> '+RED._("projects.create.auth-failed")+'</div>').appendTo(row);
1347
+
1348
+ // Repo credentials - username/password ----------------
1349
+ row = $('<div class="hide form-row projects-dialog-screen-create-row-creds"></div>').hide().appendTo(cloneAuthRows);
1350
+
1351
+ var subrow = $('<div style="width: calc(50% - 10px); display:inline-block;"></div>').appendTo(row);
1352
+ $('<label for="projects-dialog-screen-create-project-repo-user">'+RED._("projects.create.username")+'</label>').appendTo(subrow);
1353
+ projectRepoUserInput = $('<input id="projects-dialog-screen-create-project-repo-user" type="text"></input>').appendTo(subrow);
1354
+
1355
+ subrow = $('<div style="width: calc(50% - 10px); margin-left: 20px; display:inline-block;"></div>').appendTo(row);
1356
+ $('<label for="projects-dialog-screen-create-project-repo-pass">'+RED._("projects.create.password")+'</label>').appendTo(subrow);
1357
+ projectRepoPasswordInput = $('<input id="projects-dialog-screen-create-project-repo-pass" type="password"></input>').appendTo(subrow);
1358
+ // -----------------------------------------------------
1359
+
1360
+ // Repo credentials - key/passphrase -------------------
1361
+ row = $('<div class="form-row projects-dialog-screen-create-row projects-dialog-screen-create-row-sshkey"></div>').hide().appendTo(cloneAuthRows);
1362
+ subrow = $('<div style="width: calc(50% - 10px); display:inline-block;"></div>').appendTo(row);
1363
+ $('<label for="projects-dialog-screen-create-project-repo-passphrase">'+RED._("projects.create.ssh-key")+'</label>').appendTo(subrow);
1364
+ projectRepoSSHKeySelect = $("<select>",{style:"width: 100%"}).appendTo(subrow);
1365
+
1366
+ $.getJSON("settings/user/keys", function(data) {
1367
+ var count = 0;
1368
+ data.keys.forEach(function(key) {
1369
+ projectRepoSSHKeySelect.append($("<option></option>").val(key.name).text(key.name));
1370
+ count++;
1371
+ });
1372
+ if (count === 0) {
1373
+ projectRepoSSHKeySelect.addClass("input-error");
1374
+ projectRepoSSHKeySelect.attr("disabled",true);
1375
+ sshwarningRow.show();
1376
+ } else {
1377
+ projectRepoSSHKeySelect.removeClass("input-error");
1378
+ projectRepoSSHKeySelect.attr("disabled",false);
1379
+ sshwarningRow.hide();
1380
+ }
1381
+ });
1382
+ subrow = $('<div style="width: calc(50% - 10px); margin-left: 20px; display:inline-block;"></div>').appendTo(row);
1383
+ $('<label for="projects-dialog-screen-create-project-repo-passphrase">'+RED._("projects.create.passphrase")+'</label>').appendTo(subrow);
1384
+ projectRepoPassphrase = $('<input id="projects-dialog-screen-create-project-repo-passphrase" type="password"></input>').appendTo(subrow);
1385
+
1386
+ subrow = $('<div class="form-row projects-dialog-screen-create-row projects-dialog-screen-create-row-sshkey"></div>').appendTo(cloneAuthRows);
1387
+ var sshwarningRow = $('<div class="projects-dialog-screen-create-row-auth-error-no-keys"></div>').hide().appendTo(subrow);
1388
+ $('<div class="form-row"><i class="fa fa-warning"></i> '+RED._("projects.create.desc2")+'</div>').appendTo(sshwarningRow);
1389
+ subrow = $('<div style="text-align: center">').appendTo(sshwarningRow);
1390
+ $('<button class="editor-button">'+RED._("projects.create.add-ssh-key")+'</button>').appendTo(subrow).click(function(e) {
1391
+ e.preventDefault();
1392
+ $('#projects-dialog-cancel').click();
1393
+ RED.userSettings.show('gitconfig');
1394
+ setTimeout(function() {
1395
+ $("#user-settings-gitconfig-add-key").click();
1396
+ },500);
1397
+ });
1398
+ // -----------------------------------------------------
1399
+
1400
+
1401
+ // Secret - clone
1402
+ row = $('<div class="hide form-row projects-dialog-screen-create-row projects-dialog-screen-create-row-clone"></div>').appendTo(container);
1403
+ $('<label>'+RED._("projects.create.credentials-encryption-key")+'</label>').appendTo(row);
1404
+ projectSecretInput = $('<input type="password"></input>').appendTo(row);
1405
+
1406
+
1407
+ switch(options.screen||"empty") {
1408
+ case "empty": createAsEmpty.click(); break;
1409
+ case "open": openProject.click(); break;
1410
+ case "clone": createAsClone.click(); break;
1411
+ }
1412
+
1413
+ setTimeout(function() {
1414
+ if ((options.screen||"empty") !== "open") {
1415
+ projectNameInput.focus();
1416
+ } else {
1417
+ $("#projects-dialog-project-list-search").focus();
1418
+ }
1419
+ },50);
1420
+ return container;
1421
+ },
1422
+ buttons: function(options) {
1423
+ var initialLabel;
1424
+ switch (options.screen||"empty") {
1425
+ case "open": initialLabel = RED._("projects.create.open"); break;
1426
+ case "empty": initialLabel = RED._("projects.create.create"); break;
1427
+ case "clone": initialLabel = RED._("projects.create.clone"); break;
1428
+ }
1429
+ return [
1430
+ {
1431
+ id: "projects-dialog-cancel",
1432
+ text: RED._("common.label.cancel"),
1433
+ click: function() {
1434
+ $( this ).dialog( "close" );
1435
+ }
1436
+ },
1437
+ {
1438
+ id: "projects-dialog-create",
1439
+ text: initialLabel,
1440
+ class: "primary disabled",
1441
+ disabled: true,
1442
+ click: function() {
1443
+ var projectType = $(".projects-dialog-screen-create-type.selected").data('type');
1444
+ var projectData = {
1445
+ name: projectNameInput.val(),
1446
+ }
1447
+ if (projectType === 'empty') {
1448
+ projectData.summary = projectSummaryInput.val();
1449
+ projectData.files = {
1450
+ flow: projectFlowFileInput.val()
1451
+ };
1452
+ var encryptionState = $("input[name=projects-encryption-type]:checked").val();
1453
+ if (encryptionState === 'enabled') {
1454
+ projectData.credentialSecret = emptyProjectCredentialInput.val();
1455
+ } else {
1456
+ // Disabled encryption by explicitly setting credSec to false
1457
+ projectData.credentialSecret = false;
1458
+ }
1459
+
1460
+
1461
+ } else if (projectType === 'copy') {
1462
+ projectData.copy = copyProject.name;
1463
+ } else if (projectType === 'clone') {
1464
+ projectData.credentialSecret = projectSecretInput.val();
1465
+ var repoUrl = projectRepoInput.val();
1466
+ var metaData = {};
1467
+ if (/^(?:ssh|[\d\w\.\-_]+@[\w\.]+):(?:\/\/)?/.test(repoUrl)) {
1468
+ var selected = projectRepoSSHKeySelect.val();//false;//getSelectedSSHKey(projectRepoSSHKeySelect);
1469
+ if ( selected ) {
1470
+ projectData.git = {
1471
+ remotes: {
1472
+ 'origin': {
1473
+ url: repoUrl,
1474
+ keyFile: selected,
1475
+ passphrase: projectRepoPassphrase.val()
1476
+ }
1477
+ }
1478
+ };
1479
+ }
1480
+ else {
1481
+ console.log(RED._("projects.create.cant-get-ssh-key-path"));
1482
+ return;
1483
+ }
1484
+ }
1485
+ else {
1486
+ projectData.git = {
1487
+ remotes: {
1488
+ 'origin': {
1489
+ url: repoUrl,
1490
+ username: projectRepoUserInput.val(),
1491
+ password: projectRepoPasswordInput.val()
1492
+ }
1493
+ }
1494
+ };
1495
+ }
1496
+ } else if (projectType === 'open') {
1497
+ return switchProject(selectedProject.name,function(err,data) {
1498
+ dialog.dialog( "close" );
1499
+ if (err) {
1500
+ if (err.code !== 'credentials_load_failed') {
1501
+ console.log(RED._("projects.create.unexpected_error"),err)
1502
+ }
1503
+ }
1504
+ })
1505
+ }
1506
+
1507
+ $(".projects-dialog-screen-create-row-auth-error").hide();
1508
+ $("#projects-dialog-screen-create-project-repo-label small").text(RED._("projects.create.protocols"));
1509
+
1510
+ projectRepoUserInput.removeClass("input-error");
1511
+ projectRepoPasswordInput.removeClass("input-error");
1512
+ projectRepoSSHKeySelect.removeClass("input-error");
1513
+ projectRepoPassphrase.removeClass("input-error");
1514
+
1515
+ RED.deploy.setDeployInflight(true);
1516
+ RED.projects.settings.switchProject(projectData.name);
1517
+
1518
+ sendRequest({
1519
+ url: "projects",
1520
+ type: "POST",
1521
+ handleAuthFail: false,
1522
+ responses: {
1523
+ 200: function(data) {
1524
+ dialog.dialog( "close" );
1525
+ },
1526
+ 400: {
1527
+ 'project_exists': function(error) {
1528
+ console.log(RED._("projects.create.already-exists-2"));
1529
+ },
1530
+ 'git_error': function(error) {
1531
+ console.log(RED._("projects.create.git-error"),error);
1532
+ },
1533
+ 'git_connection_failed': function(error) {
1534
+ projectRepoInput.addClass("input-error");
1535
+ $("#projects-dialog-screen-create-project-repo-label small").text(RED._("projects.create.con-failed"));
1536
+ },
1537
+ 'git_not_a_repository': function(error) {
1538
+ projectRepoInput.addClass("input-error");
1539
+ $("#projects-dialog-screen-create-project-repo-label small").text(RED._("projects.create.not-git"));
1540
+ },
1541
+ 'git_repository_not_found': function(error) {
1542
+ projectRepoInput.addClass("input-error");
1543
+ $("#projects-dialog-screen-create-project-repo-label small").text(RED._("projects.create.no-resource"));
1544
+ },
1545
+ 'git_auth_failed': function(error) {
1546
+ $(".projects-dialog-screen-create-row-auth-error").show();
1547
+
1548
+ projectRepoUserInput.addClass("input-error");
1549
+ projectRepoPasswordInput.addClass("input-error");
1550
+ // getRepoAuthDetails(req);
1551
+ projectRepoSSHKeySelect.addClass("input-error");
1552
+ projectRepoPassphrase.addClass("input-error");
1553
+ },
1554
+ 'missing_flow_file': function(error) {
1555
+ // This is handled via a runtime notification.
1556
+ dialog.dialog("close");
1557
+ },
1558
+ 'missing_package_file': function(error) {
1559
+ // This is handled via a runtime notification.
1560
+ dialog.dialog("close");
1561
+ },
1562
+ 'project_empty': function(error) {
1563
+ // This is handled via a runtime notification.
1564
+ dialog.dialog("close");
1565
+ },
1566
+ 'credentials_load_failed': function(error) {
1567
+ // This is handled via a runtime notification.
1568
+ dialog.dialog("close");
1569
+ },
1570
+ '*': function(error) {
1571
+ reportUnexpectedError(error);
1572
+ $( dialog ).dialog( "close" );
1573
+ }
1574
+ }
1575
+ }
1576
+ },projectData).then(function() {
1577
+ RED.events.emit("project:change", {name:name});
1578
+ }).always(function() {
1579
+ setTimeout(function() {
1580
+ RED.deploy.setDeployInflight(false);
1581
+ },500);
1582
+ })
1583
+ }
1584
+ }
1585
+ ]
1586
+ }
1587
+ }
1588
+ })()
1589
+ }
1590
+ }
1591
+
1592
+ function switchProject(name,done) {
1593
+ RED.deploy.setDeployInflight(true);
1594
+ RED.projects.settings.switchProject(name);
1595
+ sendRequest({
1596
+ url: "projects/"+name,
1597
+ type: "PUT",
1598
+ responses: {
1599
+ 200: function(data) {
1600
+ done(null,data);
1601
+ },
1602
+ 400: {
1603
+ '*': done
1604
+ },
1605
+ }
1606
+ },{active:true}).then(function() {
1607
+ RED.events.emit("project:change", {name:name});
1608
+ }).always(function() {
1609
+ setTimeout(function() {
1610
+ RED.deploy.setDeployInflight(false);
1611
+ },500);
1612
+ })
1613
+ }
1614
+
1615
+ function deleteProject(row,name,done) {
1616
+ var cover = $('<div>').css({
1617
+ background:"white",
1618
+ position:"absolute",
1619
+ top:0,right:0,bottom:0,left:"100%",
1620
+ overflow:"hidden",
1621
+ padding: "5px 20px",
1622
+ transition: "left 0.4s",
1623
+ whitespace: "nowrap",
1624
+ width:"1000px"
1625
+ }).click(function(evt) { evt.stopPropagation(); }).appendTo(row);
1626
+ $('<span>').css({"lineHeight":"40px"}).text(RED._("projects.delete.confirm")).appendTo(cover);
1627
+ $('<button style="margin-left:20px" class="editor-button">'+RED._("common.label.cancel")+'</button>')
1628
+ .appendTo(cover)
1629
+ .click(function(e) {
1630
+ e.stopPropagation();
1631
+ cover.remove();
1632
+ done(true);
1633
+ });
1634
+ $('<button style="margin-left:20px" class="editor-button primary">'+RED._("common.label.delete")+'</button>')
1635
+ .appendTo(cover)
1636
+ .click(function(e) {
1637
+ e.stopPropagation();
1638
+ cover.remove();
1639
+ sendRequest({
1640
+ url: "projects/"+name,
1641
+ type: "DELETE",
1642
+ responses: {
1643
+ 200: function(data) {
1644
+ done(false);
1645
+ },
1646
+ 400: {
1647
+ 'unexpected_error': function(error) {
1648
+ cover.remove();
1649
+ done(true);
1650
+ }
1651
+ }
1652
+ }
1653
+ });
1654
+ });
1655
+
1656
+ setTimeout(function() {
1657
+ cover.css("left",0);
1658
+ },50);
1659
+ //
1660
+ }
1661
+
1662
+ function show(s,options) {
1663
+ if (!dialog) {
1664
+ RED.projects.init();
1665
+ }
1666
+ var screen = screens[s];
1667
+ var container = screen.content(options||{});
1668
+
1669
+ dialogBody.empty();
1670
+ var buttons = screen.buttons;
1671
+ if (typeof buttons === 'function') {
1672
+ buttons = buttons(options||{});
1673
+ }
1674
+ dialog.dialog('option','buttons',buttons);
1675
+ dialogBody.append(container);
1676
+ dialog.dialog('option','title',screen.title||"");
1677
+ dialog.dialog("open");
1678
+ dialog.dialog({position: { 'my': 'center top', 'at': 'center top+10%', 'of': window }});
1679
+ }
1680
+
1681
+ function createProjectList(options) {
1682
+ options = options||{};
1683
+ var height = options.height || "300px";
1684
+ var container = $('<div></div>',{class:"projects-dialog-project-list-container" });
1685
+ var filterTerm = "";
1686
+
1687
+ var searchDiv = $("<div>",{class:"red-ui-search-container"}).appendTo(container);
1688
+ var searchInput = $('<input id="projects-dialog-project-list-search" type="text" placeholder="'+RED._("projects.create-project-list.search")+'">').appendTo(searchDiv).searchBox({
1689
+ //data-i18n="[placeholder]menu.label.searchInput"
1690
+ delay: 200,
1691
+ change: function() {
1692
+ filterTerm = $(this).val().toLowerCase();
1693
+ list.editableList('filter');
1694
+ if (selectedListItem && !selectedListItem.is(":visible")) {
1695
+ selectedListItem.children().children().removeClass('selected');
1696
+ selectedListItem = list.children(":visible").first();
1697
+ selectedListItem.children().children().addClass('selected');
1698
+ if (options.select) {
1699
+ options.select(selectedListItem.children().data('data'));
1700
+ }
1701
+ } else {
1702
+ selectedListItem = list.children(":visible").first();
1703
+ selectedListItem.children().children().addClass('selected');
1704
+ if (options.select) {
1705
+ options.select(selectedListItem.children().data('data'));
1706
+ }
1707
+ }
1708
+ ensureSelectedIsVisible();
1709
+ }
1710
+ });
1711
+ var selectedListItem;
1712
+
1713
+ searchInput.on('keydown',function(evt) {
1714
+ if (evt.keyCode === 40) {
1715
+ evt.preventDefault();
1716
+ // Down
1717
+ var next = selectedListItem;
1718
+ if (selectedListItem) {
1719
+ do {
1720
+ next = next.next();
1721
+ } while(next.length !== 0 && !next.is(":visible"));
1722
+ if (next.length === 0) {
1723
+ return;
1724
+ }
1725
+ selectedListItem.children().children().removeClass('selected');
1726
+ } else {
1727
+ next = list.children(":visible").first();
1728
+ }
1729
+ selectedListItem = next;
1730
+ selectedListItem.children().children().addClass('selected');
1731
+ if (options.select) {
1732
+ options.select(selectedListItem.children().data('data'));
1733
+ }
1734
+ ensureSelectedIsVisible();
1735
+ } else if (evt.keyCode === 38) {
1736
+ evt.preventDefault();
1737
+ // Up
1738
+ var prev = selectedListItem;
1739
+ if (selectedListItem) {
1740
+ do {
1741
+ prev = prev.prev();
1742
+ } while(prev.length !== 0 && !prev.is(":visible"));
1743
+ if (prev.length === 0) {
1744
+ return;
1745
+ }
1746
+ selectedListItem.children().children().removeClass('selected');
1747
+ } else {
1748
+ prev = list.children(":visible").first();
1749
+ }
1750
+ selectedListItem = prev;
1751
+ selectedListItem.children().children().addClass('selected');
1752
+ if (options.select) {
1753
+ options.select(selectedListItem.children().data('data'));
1754
+ }
1755
+ ensureSelectedIsVisible();
1756
+ } else if (evt.keyCode === 13) {
1757
+ evt.preventDefault();
1758
+ // Enter
1759
+ if (selectedListItem) {
1760
+ if (options.dblclick) {
1761
+ options.dblclick(selectedListItem.children().data('data'));
1762
+ }
1763
+ }
1764
+ }
1765
+ });
1766
+
1767
+ searchInput.i18n();
1768
+
1769
+ var ensureSelectedIsVisible = function() {
1770
+ var selectedEntry = list.find(".projects-dialog-project-list-entry.selected").parent().parent();
1771
+ if (selectedEntry.length === 1) {
1772
+ var scrollWindow = listContainer;
1773
+ var scrollHeight = scrollWindow.height();
1774
+ var scrollOffset = scrollWindow.scrollTop();
1775
+ var y = selectedEntry.position().top;
1776
+ var h = selectedEntry.height();
1777
+ if (y+h > scrollHeight) {
1778
+ scrollWindow.animate({scrollTop: '-='+(scrollHeight-y-h)},50);
1779
+ } else if (y<0) {
1780
+ scrollWindow.animate({scrollTop: '+='+y},50);
1781
+ }
1782
+ }
1783
+ }
1784
+
1785
+ var listContainer = $('<div></div>',{class:"projects-dialog-project-list-inner-container" }).appendTo(container);
1786
+
1787
+ var list = $('<ol>',{class:"projects-dialog-project-list"}).appendTo(listContainer).editableList({
1788
+ addButton: false,
1789
+ height:"auto",
1790
+ scrollOnAdd: false,
1791
+ addItem: function(row,index,entry) {
1792
+ var header = $('<div></div>',{class:"projects-dialog-project-list-entry"}).appendTo(row);
1793
+ $('<span class="projects-dialog-project-list-entry-icon"><i class="fa fa-archive"></i></span>').appendTo(header);
1794
+ $('<span class="projects-dialog-project-list-entry-name" style=""></span>').text(entry.name).appendTo(header);
1795
+ if (activeProject && activeProject.name === entry.name) {
1796
+ header.addClass("projects-list-entry-current");
1797
+ $('<span class="projects-dialog-project-list-entry-current">'+RED._("projects.create-project-list.current")+'</span>').appendTo(header);
1798
+ if (options.canSelectActive === false) {
1799
+ // active project cannot be selected; so skip the rest
1800
+ return
1801
+ }
1802
+ }
1803
+
1804
+ header.addClass("selectable");
1805
+
1806
+ var tools = $('<div class="projects-dialog-project-list-entry-tools"></div>').appendTo(header);
1807
+ $('<button class="editor-button editor-button-small" style="float: right;"><i class="fa fa-trash"></i></button>')
1808
+ .appendTo(tools)
1809
+ .click(function(e) {
1810
+ e.stopPropagation();
1811
+ e.preventDefault();
1812
+ deleteProject(row,entry.name, function(cancelled) {
1813
+ if (!cancelled) {
1814
+ row.fadeOut(300,function() {
1815
+ list.editableList('removeItem',entry);
1816
+ if (options.delete) {
1817
+ options.delete(entry);
1818
+ }
1819
+ });
1820
+ }
1821
+ })
1822
+ });
1823
+
1824
+
1825
+ row.click(function(evt) {
1826
+ $('.projects-dialog-project-list-entry').removeClass('selected');
1827
+ header.addClass('selected');
1828
+ selectedListItem = row.parent();
1829
+ if (options.select) {
1830
+ options.select(entry);
1831
+ }
1832
+ ensureSelectedIsVisible();
1833
+ searchInput.focus();
1834
+ })
1835
+ if (options.dblclick) {
1836
+ row.dblclick(function(evt) {
1837
+ evt.preventDefault();
1838
+ options.dblclick(entry);
1839
+ })
1840
+ }
1841
+ },
1842
+ filter: function(data) {
1843
+ if (filterTerm === "") { return true; }
1844
+ return data.name.toLowerCase().indexOf(filterTerm) !== -1;
1845
+ }
1846
+ });
1847
+ $.getJSON("projects", function(data) {
1848
+ data.projects.forEach(function(project) {
1849
+ list.editableList('addItem',{name:project});
1850
+ });
1851
+ })
1852
+ return container;
1853
+ }
1854
+
1855
+
1856
+
1857
+ function requireCleanWorkspace(done) {
1858
+ if (RED.nodes.dirty()) {
1859
+ var message = RED._("projects.require-clean.confirm");
1860
+ var cleanNotification = RED.notify(message,{
1861
+ type:"info",
1862
+ fixed: true,
1863
+ modal: true,
1864
+ buttons: [
1865
+ {
1866
+ //id: "node-dialog-delete",
1867
+ //class: 'leftButton',
1868
+ text: RED._("common.label.cancel"),
1869
+ click: function() {
1870
+ cleanNotification.close();
1871
+ done(true);
1872
+ }
1873
+ },{
1874
+ text: RED._("common.label.cont"),
1875
+ click: function() {
1876
+ cleanNotification.close();
1877
+ done(false);
1878
+ }
1879
+ }
1880
+ ]
1881
+ });
1882
+
1883
+ }
1884
+ }
1885
+
1886
+ function sendRequest(options,body) {
1887
+ // dialogBody.hide();
1888
+ // console.log(options.url,body);
1889
+ if (options.requireCleanWorkspace && RED.nodes.dirty()) {
1890
+ var thenCallback;
1891
+ var alwaysCallback;
1892
+ requireCleanWorkspace(function(cancelled) {
1893
+ if (cancelled) {
1894
+ if (options.cancel) {
1895
+ options.cancel();
1896
+ if (alwaysCallback) {
1897
+ alwaysCallback();
1898
+ }
1899
+ }
1900
+ } else {
1901
+ delete options.requireCleanWorkspace;
1902
+ sendRequest(options,body).then(function() {
1903
+ if (thenCallback) {
1904
+ thenCallback();
1905
+ }
1906
+ }).always(function() {
1907
+ if (alwaysCallback) {
1908
+ alwaysCallback();
1909
+ }
1910
+
1911
+ })
1912
+ }
1913
+ })
1914
+ // What follows is a very hacky Promise-like api thats good enough
1915
+ // for our needs.
1916
+ return {
1917
+ then: function(done) {
1918
+ thenCallback = done;
1919
+ return { always: function(done) { alwaysCallback = done; }}
1920
+ },
1921
+ always: function(done) { alwaysCallback = done; }
1922
+ }
1923
+ }
1924
+
1925
+ var start = Date.now();
1926
+ // TODO: this is specific to the dialog-based requests
1927
+ $(".projects-dialog-spinner").show();
1928
+ $("#projects-dialog").parent().find(".ui-dialog-buttonset").children().css("visibility","hidden")
1929
+ if (body) {
1930
+ options.data = JSON.stringify(body);
1931
+ options.contentType = "application/json; charset=utf-8";
1932
+ }
1933
+ var resultCallback;
1934
+ var resultCallbackArgs;
1935
+ return $.ajax(options).done(function(data,textStatus,xhr) {
1936
+ if (options.responses && options.responses[200]) {
1937
+ resultCallback = options.responses[200];
1938
+ resultCallbackArgs = data;
1939
+ }
1940
+ }).fail(function(xhr,textStatus,err) {
1941
+ if (options.responses && options.responses[xhr.status]) {
1942
+ var responses = options.responses[xhr.status];
1943
+ if (typeof responses === 'function') {
1944
+ resultCallback = responses;
1945
+ resultCallbackArgs = {error:responses.statusText};
1946
+ return;
1947
+ } else if (options.handleAuthFail !== false && xhr.responseJSON.code === 'git_auth_failed') {
1948
+ var url = activeProject.git.remotes[xhr.responseJSON.remote||options.remote||'origin'].fetch;
1949
+
1950
+ var message = $('<div>'+
1951
+ '<div class="form-row">'+RED._("projects.send-req.auth-req")+':</div>'+
1952
+ '<div class="form-row"><div style="margin-left: 20px;">'+url+'</div></div>'+
1953
+ '</div>');
1954
+
1955
+ var isSSH = false;
1956
+ if (/^https?:\/\//.test(url)) {
1957
+ $('<div class="form-row"><label for="projects-user-auth-username">'+RED._("projects.send-req.username")+'</label><input id="projects-user-auth-username" type="text"></input></div>'+
1958
+ '<div class="form-row"><label for=projects-user-auth-password">'+RED._("projects.send-req.password")+'</label><input id="projects-user-auth-password" type="password"></input></div>').appendTo(message);
1959
+ } else if (/^(?:ssh|[\d\w\.\-_]+@[\w\.]+):(?:\/\/)?/.test(url)) {
1960
+ isSSH = true;
1961
+ var row = $('<div class="form-row"></div>').appendTo(message);
1962
+ $('<label for="projects-user-auth-key">SSH Key</label>').appendTo(row);
1963
+ var projectRepoSSHKeySelect = $('<select id="projects-user-auth-key">').width('70%').appendTo(row);
1964
+ $.getJSON("settings/user/keys", function(data) {
1965
+ var count = 0;
1966
+ data.keys.forEach(function(key) {
1967
+ projectRepoSSHKeySelect.append($("<option></option>").val(key.name).text(key.name));
1968
+ count++;
1969
+ });
1970
+ if (count === 0) {
1971
+ //TODO: handle no keys yet setup
1972
+ }
1973
+ });
1974
+ row = $('<div class="form-row"></div>').appendTo(message);
1975
+ $('<label for="projects-user-auth-passphrase">'+RED._("projects.send-req.passphrase")+'</label>').appendTo(row);
1976
+ $('<input id="projects-user-auth-passphrase" type="password"></input>').appendTo(row);
1977
+ }
1978
+
1979
+ var notification = RED.notify(message,{
1980
+ type:"error",
1981
+ fixed: true,
1982
+ modal: true,
1983
+ buttons: [
1984
+ {
1985
+ //id: "node-dialog-delete",
1986
+ //class: 'leftButton',
1987
+ text: RED._("common.label.cancel"),
1988
+ click: function() {
1989
+ notification.close();
1990
+ }
1991
+ },{
1992
+ text: '<span><i class="fa fa-refresh"></i> ' +RED._("projects.send-req.retry") +'</span>',
1993
+ click: function() {
1994
+ body = body || {};
1995
+ var authBody = {};
1996
+ if (isSSH) {
1997
+ authBody.keyFile = $('#projects-user-auth-key').val();
1998
+ authBody.passphrase = $('#projects-user-auth-passphrase').val();
1999
+ } else {
2000
+ authBody.username = $('#projects-user-auth-username').val();
2001
+ authBody.password = $('#projects-user-auth-password').val();
2002
+ }
2003
+ var done = function(err) {
2004
+ if (err) {
2005
+ console.log(RED._("projects.send-req.update-failed"));
2006
+ console.log(err);
2007
+ } else {
2008
+ sendRequest(options,body);
2009
+ notification.close();
2010
+ }
2011
+
2012
+ }
2013
+ sendRequest({
2014
+ url: "projects/"+activeProject.name+"/remotes/"+(xhr.responseJSON.remote||options.remote||'origin'),
2015
+ type: "PUT",
2016
+ responses: {
2017
+ 0: function(error) {
2018
+ done(error,null);
2019
+ },
2020
+ 200: function(data) {
2021
+ done(null,data);
2022
+ },
2023
+ 400: {
2024
+ 'unexpected_error': function(error) {
2025
+ done(error,null);
2026
+ }
2027
+ },
2028
+ }
2029
+ },{auth:authBody});
2030
+ }
2031
+ }
2032
+ ]
2033
+ });
2034
+ return;
2035
+ } else if (responses[xhr.responseJSON.code]) {
2036
+ resultCallback = responses[xhr.responseJSON.code];
2037
+ resultCallbackArgs = xhr.responseJSON;
2038
+ return;
2039
+ } else if (responses['*']) {
2040
+ resultCallback = responses['*'];
2041
+ resultCallbackArgs = xhr.responseJSON;
2042
+ return;
2043
+ }
2044
+ }
2045
+ console.log(responses)
2046
+ console.log(RED._("projects.send-req.unhandled")+":");
2047
+ console.log(xhr);
2048
+ console.log(textStatus);
2049
+ console.log(err);
2050
+ }).always(function() {
2051
+ var delta = Date.now() - start;
2052
+ delta = Math.max(0,500-delta);
2053
+ setTimeout(function() {
2054
+ // dialogBody.show();
2055
+ $(".projects-dialog-spinner").hide();
2056
+ $("#projects-dialog").parent().find(".ui-dialog-buttonset").children().css("visibility","")
2057
+ if (resultCallback) {
2058
+ resultCallback(resultCallbackArgs)
2059
+ }
2060
+ },delta);
2061
+ });
2062
+ }
2063
+
2064
+ function createBranchList(options) {
2065
+ var branchFilterTerm = "";
2066
+ var branchFilterCreateItem;
2067
+ var branches = [];
2068
+ var branchPrefix = "";
2069
+ var container = $('<div class="projects-branch-list">').appendTo(options.container);
2070
+
2071
+ var branchFilter = $('<input type="text">').attr('placeholder',options.placeholder).appendTo(container).searchBox({
2072
+ delay: 200,
2073
+ change: function() {
2074
+ branchFilterTerm = $(this).val();
2075
+ if (/(\.\.|\/\.|[?*[~^: \\]|\/\/|\/.$|\/$)/.test(branchFilterTerm)) {
2076
+ if (!branchFilterCreateItem.hasClass("input-error")) {
2077
+ branchFilterCreateItem.addClass("input-error");
2078
+ branchFilterCreateItem.find("i").addClass("fa-warning").removeClass("fa-code-fork");
2079
+ }
2080
+ branchFilterCreateItem.find("span").text(RED._("projects.create-branch-list.invalid")+": "+branchPrefix+branchFilterTerm);
2081
+ } else {
2082
+ if (branchFilterCreateItem.hasClass("input-error")) {
2083
+ branchFilterCreateItem.removeClass("input-error");
2084
+ branchFilterCreateItem.find("i").removeClass("fa-warning").addClass("fa-code-fork");
2085
+ }
2086
+ branchFilterCreateItem.find(".sidebar-version-control-branch-list-entry-create-name").text(branchPrefix+branchFilterTerm);
2087
+ }
2088
+ branchList.editableList("filter");
2089
+ }
2090
+ });
2091
+ var branchList = $("<ol>",{style:"height: 130px;"}).appendTo(container);
2092
+ branchList.editableList({
2093
+ addButton: false,
2094
+ scrollOnAdd: false,
2095
+ addItem: function(row,index,entry) {
2096
+ var container = $('<div class="sidebar-version-control-branch-list-entry">').appendTo(row);
2097
+ if (!entry.hasOwnProperty('commit')) {
2098
+ branchFilterCreateItem = container;
2099
+ $('<i class="fa fa-code-fork"></i>').appendTo(container);
2100
+ $('<span>').text(RED._("projects.create-branch-list.create")+":").appendTo(container);
2101
+ $('<div class="sidebar-version-control-branch-list-entry-create-name" style="margin-left: 10px;">').text(entry.name).appendTo(container);
2102
+ } else {
2103
+ $('<i class="fa fa-code-fork"></i>').appendTo(container);
2104
+ $('<span>').text(entry.name).appendTo(container);
2105
+ if (entry.current) {
2106
+ container.addClass("selected");
2107
+ $('<span class="current"></span>').text(options.currentLabel||RED._("projects.create-branch-list.current")).appendTo(container);
2108
+ }
2109
+ }
2110
+ container.click(function(evt) {
2111
+ evt.preventDefault();
2112
+ if ($(this).hasClass('input-error')) {
2113
+ return;
2114
+ }
2115
+ var body = {};
2116
+ if (!entry.hasOwnProperty('commit')) {
2117
+ body.name = branchFilter.val();
2118
+ body.create = true;
2119
+ if (options.remote) {
2120
+ body.name = options.remote()+"/"+body.name;
2121
+ }
2122
+ } else {
2123
+ if ($(this).hasClass('selected')) {
2124
+ body.current = true;
2125
+ }
2126
+ body.name = entry.name;
2127
+ }
2128
+ if (options.onselect) {
2129
+ options.onselect(body);
2130
+ }
2131
+ });
2132
+ },
2133
+ filter: function(data) {
2134
+ var isCreateEntry = (!data.hasOwnProperty('commit'));
2135
+ return (
2136
+ isCreateEntry &&
2137
+ (
2138
+ branchFilterTerm !== "" &&
2139
+ branches.indexOf(branchPrefix+branchFilterTerm) === -1
2140
+ )
2141
+ ) ||
2142
+ (
2143
+ !isCreateEntry &&
2144
+ data.name.indexOf(branchFilterTerm) !== -1
2145
+ );
2146
+ }
2147
+ });
2148
+ return {
2149
+ refresh: function(url) {
2150
+ branchFilter.searchBox("value","");
2151
+ branchList.editableList('empty');
2152
+ var start = Date.now();
2153
+ var spinner = addSpinnerOverlay(container).addClass("projects-dialog-spinner-contain");
2154
+ if (options.remote) {
2155
+ branchPrefix = options.remote()+"/";
2156
+ } else {
2157
+ branchPrefix = "";
2158
+ }
2159
+
2160
+ sendRequest({
2161
+ url: url,
2162
+ type: "GET",
2163
+ responses: {
2164
+ 0: function(error) {
2165
+ console.log(error);
2166
+ },
2167
+ 200: function(result) {
2168
+ branches = result.branches;
2169
+ result.branches.forEach(function(b) {
2170
+ branchList.editableList('addItem',b);
2171
+ });
2172
+ branchList.editableList('addItem',{});
2173
+ setTimeout(function() {
2174
+ spinner.remove();
2175
+ },Math.max(300-(Date.now() - start),0));
2176
+ },
2177
+ 400: {
2178
+ 'git_connection_failed': function(error) {
2179
+ RED.notify(error.message,'error');
2180
+ },
2181
+ 'git_not_a_repository': function(error) {
2182
+ RED.notify(error.message,'error');
2183
+ },
2184
+ 'git_repository_not_found': function(error) {
2185
+ RED.notify(error.message,'error');
2186
+ },
2187
+ 'unexpected_error': function(error) {
2188
+ reportUnexpectedError(error);
2189
+ }
2190
+ }
2191
+ }
2192
+ })
2193
+ },
2194
+ // addItem: function(data) { branchList.editableList('addItem',data) },
2195
+ filter: function() { branchList.editableList('filter') },
2196
+ focus: function() { branchFilter.focus() }
2197
+ }
2198
+ }
2199
+
2200
+ function addSpinnerOverlay(container) {
2201
+ var spinner = $('<div class="projects-dialog-spinner"><img src="red/images/spin.svg"/></div>').appendTo(container);
2202
+ return spinner;
2203
+ }
2204
+
2205
+ function init() {
2206
+ dialog = $('<div id="projects-dialog" class="hide kumologica-core-dialog projects-edit-form"><form class="form-horizontal"></form><div class="projects-dialog-spinner hide"><img src="red/images/spin.svg"/></div></div>')
2207
+ .appendTo("body")
2208
+ .dialog({
2209
+ modal: true,
2210
+ autoOpen: false,
2211
+ width: 600,
2212
+ resizable: false,
2213
+ open: function(e) {
2214
+ $(this).parent().find(".ui-dialog-titlebar-close").hide();
2215
+ // $("#header-shade").show();
2216
+ // $("#editor-shade").show();
2217
+ // $("#palette-shade").show();
2218
+ // $("#sidebar-shade").show();
2219
+ },
2220
+ close: function(e) {
2221
+ // $("#header-shade").hide();
2222
+ // $("#editor-shade").hide();
2223
+ // $("#palette-shade").hide();
2224
+ // $("#sidebar-shade").hide();
2225
+ }
2226
+ });
2227
+ dialogBody = dialog.find("form");
2228
+
2229
+ RED.actions.add("core:new-project",RED.projects.newProject);
2230
+ RED.actions.add("core:open-project",RED.projects.selectProject);
2231
+ RED.actions.add("core:show-project-settings",RED.projects.settings.show);
2232
+ var projectsAPI = {
2233
+ sendRequest:sendRequest,
2234
+ createBranchList:createBranchList,
2235
+ addSpinnerOverlay:addSpinnerOverlay,
2236
+ reportUnexpectedError:reportUnexpectedError
2237
+ };
2238
+ RED.projects.settings.init(projectsAPI);
2239
+ RED.projects.userSettings.init(projectsAPI);
2240
+ RED.sidebar.versionControl.init(projectsAPI);
2241
+ initScreens();
2242
+ // initSidebar();
2243
+ }
2244
+
2245
+ function createDefaultFileSet() {
2246
+ if (!activeProject) {
2247
+ throw new Error(RED._("projects.create-default-file-set.no-active"));
2248
+ } else if (!activeProject.empty) {
2249
+ throw new Error(RED._("projects.create-default-file-set.no-empty"));
2250
+ }
2251
+ if (!RED.user.hasPermission("projects.write")) {
2252
+ RED.notify(RED._("user.errors.notAuthorized"),"error");
2253
+ return;
2254
+ }
2255
+ createProjectOptions = {};
2256
+ show('default-files',{existingProject: true});
2257
+ }
2258
+ function createDefaultPackageFile() {
2259
+ RED.deploy.setDeployInflight(true);
2260
+ RED.projects.settings.switchProject(activeProject.name);
2261
+
2262
+ var method = "PUT";
2263
+ var url = "projects/"+activeProject.name;
2264
+ var createProjectOptions = {
2265
+ initialise: true
2266
+ };
2267
+ sendRequest({
2268
+ url: url,
2269
+ type: method,
2270
+ requireCleanWorkspace: true,
2271
+ handleAuthFail: false,
2272
+ responses: {
2273
+ 200: function(data) { },
2274
+ 400: {
2275
+ 'git_error': function(error) {
2276
+ console.log(RED._("projects.create-default-file-set.git-error"),error);
2277
+ },
2278
+ 'missing_flow_file': function(error) {
2279
+ // This is a natural next error - but let the runtime event
2280
+ // trigger the dialog rather than double-report it.
2281
+ $( dialog ).dialog( "close" );
2282
+ },
2283
+ '*': function(error) {
2284
+ reportUnexpectedError(error);
2285
+ $( dialog ).dialog( "close" );
2286
+ }
2287
+ }
2288
+ }
2289
+ },createProjectOptions).always(function() {
2290
+ setTimeout(function() {
2291
+ RED.deploy.setDeployInflight(false);
2292
+ },500);
2293
+ })
2294
+ }
2295
+
2296
+ function refresh(done) {
2297
+ $.getJSON("projects",function(data) {
2298
+ if (data.active) {
2299
+ $.getJSON("projects/"+data.active, function(project) {
2300
+ activeProject = project;
2301
+ RED.sidebar.versionControl.refresh(true);
2302
+ if (done) {
2303
+ done(activeProject);
2304
+ }
2305
+ });
2306
+ } else {
2307
+ if (done) {
2308
+ done(null);
2309
+ }
2310
+ }
2311
+ });
2312
+ }
2313
+
2314
+
2315
+ function showNewProjectScreen() {
2316
+ createProjectOptions = {};
2317
+ if (!activeProject) {
2318
+ show('welcome');
2319
+ } else {
2320
+ show('create',{screen:'empty'})
2321
+ }
2322
+ }
2323
+
2324
+ return {
2325
+ init: init,
2326
+ showStartup: function() {
2327
+ if (!RED.user.hasPermission("projects.write")) {
2328
+ RED.notify(RED._("user.errors.notAuthorized"),"error");
2329
+ return;
2330
+ }
2331
+ show('welcome');
2332
+ },
2333
+ newProject: function() {
2334
+ if (!RED.user.hasPermission("projects.write")) {
2335
+ RED.notify(RED._("user.errors.notAuthorized"),"error");
2336
+ return;
2337
+ }
2338
+
2339
+ if (RED.nodes.dirty()) {
2340
+ return requireCleanWorkspace(function(cancelled) {
2341
+ if (!cancelled) {
2342
+ showNewProjectScreen();
2343
+ }
2344
+ })
2345
+ } else {
2346
+ showNewProjectScreen();
2347
+ }
2348
+ },
2349
+ selectProject: function() {
2350
+ if (!RED.user.hasPermission("projects.write")) {
2351
+ RED.notify(RED._("user.errors.notAuthorized"),"error");
2352
+ return;
2353
+ }
2354
+ if (RED.nodes.dirty()) {
2355
+ return requireCleanWorkspace(function(cancelled) {
2356
+ if (!cancelled) {
2357
+ show('create',{screen:'open'})
2358
+ }
2359
+ })
2360
+ } else {
2361
+ show('create',{screen:'open'})
2362
+ }
2363
+ },
2364
+ showCredentialsPrompt: function() { //TODO: rename this function
2365
+ if (!RED.user.hasPermission("projects.write")) {
2366
+ RED.notify(RED._("user.errors.notAuthorized"),"error");
2367
+ return;
2368
+ }
2369
+ RED.projects.settings.show('settings');
2370
+ },
2371
+ showFilesPrompt: function() { //TODO: rename this function
2372
+ if (!RED.user.hasPermission("projects.write")) {
2373
+ RED.notify(RED._("user.errors.notAuthorized"),"error");
2374
+ return;
2375
+ }
2376
+ RED.projects.settings.show('settings');
2377
+ setTimeout(function() {
2378
+ $("#project-settings-tab-settings-file-edit").click();
2379
+ },200)
2380
+ },
2381
+ showProjectDependencies: function() {
2382
+ RED.projects.settings.show('deps');
2383
+ },
2384
+ createDefaultFileSet: createDefaultFileSet,
2385
+ createDefaultPackageFile: createDefaultPackageFile,
2386
+ // showSidebar: showSidebar,
2387
+ refresh: refresh,
2388
+ editProject: function() {
2389
+ RED.projects.settings.show();
2390
+ },
2391
+ getActiveProject: function() {
2392
+ return activeProject;
2393
+ }
2394
+ }
2395
+ })();