@nyaruka/temba-components 0.129.1 → 0.129.3

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 (583) hide show
  1. package/.github/workflows/build.yml +6 -5
  2. package/.github/workflows/coverage.yml +80 -0
  3. package/CHANGELOG.md +32 -0
  4. package/README.md +6 -0
  5. package/check-coverage.js +133 -0
  6. package/demo/components/alert/example.html +71 -0
  7. package/demo/components/button/example.html +167 -0
  8. package/demo/{chart → components/chart}/example.html +3 -3
  9. package/demo/components/chart/horizontal-demo.html +160 -0
  10. package/demo/components/checkbox/example.html +68 -0
  11. package/demo/components/compose/example.html +69 -0
  12. package/demo/components/datepicker/example.html +3 -3
  13. package/demo/components/datepicker/range-picker-demo.html +2 -2
  14. package/demo/{dialog → components/dialog}/example.html +3 -3
  15. package/demo/components/dropdown/example.html +95 -0
  16. package/demo/{flow → components/flow}/example.html +1 -1
  17. package/demo/{misc → components/misc}/example.html +3 -3
  18. package/demo/components/progress/example.html +62 -0
  19. package/demo/components/select/drag-and-drop.html +162 -0
  20. package/demo/components/select/example.html +76 -0
  21. package/demo/components/select/multi.html +72 -0
  22. package/demo/components/slider/example.html +55 -0
  23. package/demo/{sortable-list → components/sortable-list}/example.html +3 -3
  24. package/demo/components/tabs/example.html +91 -0
  25. package/demo/{textinput → components/textinput}/completion.html +3 -3
  26. package/demo/components/textinput/example.html +141 -0
  27. package/demo/{webchat → components/webchat}/example.html +3 -3
  28. package/demo/data/flows/sample-flow.json +107 -100
  29. package/demo/index.html +21 -21
  30. package/demo/static/css/styles.css +253 -0
  31. package/demo/sticky-note-demo.html +88 -85
  32. package/demo/styles.css +24 -0
  33. package/dist/locales/es.js +5 -5
  34. package/dist/locales/es.js.map +1 -1
  35. package/dist/locales/fr.js +5 -5
  36. package/dist/locales/fr.js.map +1 -1
  37. package/dist/locales/locale-codes.js +2 -11
  38. package/dist/locales/locale-codes.js.map +1 -1
  39. package/dist/locales/pt.js +5 -5
  40. package/dist/locales/pt.js.map +1 -1
  41. package/dist/temba-components.js +893 -476
  42. package/dist/temba-components.js.map +1 -1
  43. package/generate-coverage-badge.sh +69 -0
  44. package/out-tsc/src/{vectoricon/index.js → Icons.js} +1 -1
  45. package/out-tsc/src/Icons.js.map +1 -0
  46. package/out-tsc/src/display/Alert.js.map +1 -0
  47. package/out-tsc/src/display/Anchor.js.map +1 -0
  48. package/out-tsc/src/display/Button.js.map +1 -0
  49. package/out-tsc/src/{charcount → display}/CharCount.js +159 -2
  50. package/out-tsc/src/display/CharCount.js.map +1 -0
  51. package/out-tsc/src/display/Chat.js.map +1 -0
  52. package/out-tsc/src/display/ContactName.js.map +1 -0
  53. package/out-tsc/src/display/ContactUrn.js.map +1 -0
  54. package/out-tsc/src/display/Dropdown.js.map +1 -0
  55. package/out-tsc/src/{vectoricon/VectorIcon.js → display/Icon.js} +2 -2
  56. package/out-tsc/src/display/Icon.js.map +1 -0
  57. package/out-tsc/src/display/Label.js.map +1 -0
  58. package/out-tsc/src/{leafletmap → display}/LeafletMap.js +16 -1
  59. package/out-tsc/src/display/LeafletMap.js.map +1 -0
  60. package/out-tsc/src/display/Lightbox.js.map +1 -0
  61. package/out-tsc/src/{loading → display}/Loading.js.map +1 -1
  62. package/out-tsc/src/{options → display}/Options.js.map +1 -1
  63. package/out-tsc/src/display/ProgressBar.js.map +1 -0
  64. package/out-tsc/src/display/TembaDate.js.map +1 -0
  65. package/out-tsc/src/display/TembaUser.js.map +1 -0
  66. package/out-tsc/src/display/Thumbnail.js.map +1 -0
  67. package/out-tsc/src/{tip → display}/Tip.js +1 -2
  68. package/out-tsc/src/display/Tip.js.map +1 -0
  69. package/out-tsc/src/display/Toast.js.map +1 -0
  70. package/out-tsc/src/display/sms/gsmsplitter.js.map +1 -0
  71. package/out-tsc/src/display/sms/gsmvalidator.js.map +1 -0
  72. package/out-tsc/src/display/sms/index.js.map +1 -0
  73. package/out-tsc/src/display/sms/unicodesplitter.js.map +1 -0
  74. package/out-tsc/src/events.js +2 -0
  75. package/out-tsc/src/events.js.map +1 -0
  76. package/out-tsc/src/excellent/ExcellentParser.js.map +1 -0
  77. package/out-tsc/src/excellent/helpers.js.map +1 -0
  78. package/out-tsc/src/flow/Editor.js +533 -140
  79. package/out-tsc/src/flow/Editor.js.map +1 -1
  80. package/out-tsc/src/flow/EditorNode.js +287 -20
  81. package/out-tsc/src/flow/EditorNode.js.map +1 -1
  82. package/out-tsc/src/flow/Plumber.js +154 -74
  83. package/out-tsc/src/flow/Plumber.js.map +1 -1
  84. package/out-tsc/src/flow/StickyNote.js +153 -9
  85. package/out-tsc/src/flow/StickyNote.js.map +1 -1
  86. package/out-tsc/src/flow/config.js +88 -18
  87. package/out-tsc/src/flow/config.js.map +1 -1
  88. package/out-tsc/src/flow/render.js +327 -10
  89. package/out-tsc/src/flow/render.js.map +1 -1
  90. package/out-tsc/src/{checkbox → form}/Checkbox.js +2 -2
  91. package/out-tsc/src/form/Checkbox.js.map +1 -0
  92. package/out-tsc/src/{colorpicker → form}/ColorPicker.js +1 -1
  93. package/out-tsc/src/form/ColorPicker.js.map +1 -0
  94. package/out-tsc/src/{completion → form}/Completion.js +2 -2
  95. package/out-tsc/src/form/Completion.js.map +1 -0
  96. package/out-tsc/src/{compose → form}/Compose.js +1 -1
  97. package/out-tsc/src/form/Compose.js.map +1 -0
  98. package/out-tsc/src/{contactsearch → form}/ContactSearch.js +2 -2
  99. package/out-tsc/src/form/ContactSearch.js.map +1 -0
  100. package/out-tsc/src/form/CroppieCSS.js.map +1 -0
  101. package/out-tsc/src/{datepicker → form}/DatePicker.js +1 -1
  102. package/out-tsc/src/form/DatePicker.js.map +1 -0
  103. package/out-tsc/src/{FormElement.js → form/FormElement.js} +1 -1
  104. package/out-tsc/src/form/FormElement.js.map +1 -0
  105. package/out-tsc/src/form/FormField.js.map +1 -0
  106. package/out-tsc/src/{imagepicker → form}/ImagePicker.js +2 -2
  107. package/out-tsc/src/form/ImagePicker.js.map +1 -0
  108. package/out-tsc/src/{mediapicker → form}/MediaPicker.js +1 -1
  109. package/out-tsc/src/form/MediaPicker.js.map +1 -0
  110. package/out-tsc/src/{datepicker → form}/RangePicker.js +3 -2
  111. package/out-tsc/src/form/RangePicker.js.map +1 -0
  112. package/out-tsc/src/{slider → form}/TembaSlider.js +1 -1
  113. package/out-tsc/src/form/TembaSlider.js.map +1 -0
  114. package/out-tsc/src/{templates → form}/TemplateEditor.js +1 -1
  115. package/out-tsc/src/form/TemplateEditor.js.map +1 -0
  116. package/out-tsc/src/{textinput → form}/TextInput.js +3 -3
  117. package/out-tsc/src/form/TextInput.js.map +1 -0
  118. package/out-tsc/src/{omnibox → form/select}/Omnibox.js +2 -2
  119. package/out-tsc/src/form/select/Omnibox.js.map +1 -0
  120. package/out-tsc/src/{select → form/select}/PopupSelect.js +1 -1
  121. package/out-tsc/src/form/select/PopupSelect.js.map +1 -0
  122. package/out-tsc/src/{select → form/select}/Select.js +86 -87
  123. package/out-tsc/src/form/select/Select.js.map +1 -0
  124. package/out-tsc/src/{select → form/select}/UserSelect.js +1 -1
  125. package/out-tsc/src/form/select/UserSelect.js.map +1 -0
  126. package/out-tsc/src/{select → form/select}/WorkspaceSelect.js +1 -1
  127. package/out-tsc/src/form/select/WorkspaceSelect.js.map +1 -0
  128. package/out-tsc/src/interfaces.js +1 -0
  129. package/out-tsc/src/interfaces.js.map +1 -1
  130. package/out-tsc/src/layout/Dialog.js.map +1 -0
  131. package/out-tsc/src/layout/Mask.js.map +1 -0
  132. package/out-tsc/src/{dialog → layout}/Modax.js.map +1 -1
  133. package/out-tsc/src/layout/Resizer.js.map +1 -0
  134. package/out-tsc/src/layout/Tab.js.map +1 -0
  135. package/out-tsc/src/layout/TabPane.js.map +1 -0
  136. package/out-tsc/src/list/NotificationList.js +1 -1
  137. package/out-tsc/src/list/NotificationList.js.map +1 -1
  138. package/out-tsc/src/list/RunList.js +1 -1
  139. package/out-tsc/src/list/RunList.js.map +1 -1
  140. package/out-tsc/src/list/ShortcutList.js.map +1 -1
  141. package/out-tsc/src/list/TembaMenu.js +1 -1
  142. package/out-tsc/src/list/TembaMenu.js.map +1 -1
  143. package/out-tsc/src/list/TicketList.js +1 -1
  144. package/out-tsc/src/list/TicketList.js.map +1 -1
  145. package/out-tsc/src/{aliaseditor → live}/AliasEditor.js +1 -1
  146. package/out-tsc/src/live/AliasEditor.js.map +1 -0
  147. package/out-tsc/src/{contacts → live}/ContactBadges.js +1 -1
  148. package/out-tsc/src/live/ContactBadges.js.map +1 -0
  149. package/out-tsc/src/{contacts → live}/ContactChat.js +79 -3
  150. package/out-tsc/src/live/ContactChat.js.map +1 -0
  151. package/out-tsc/src/{contacts → live}/ContactDetails.js +1 -1
  152. package/out-tsc/src/live/ContactDetails.js.map +1 -0
  153. package/out-tsc/src/{contacts → live}/ContactFieldEditor.js +2 -2
  154. package/out-tsc/src/live/ContactFieldEditor.js.map +1 -0
  155. package/out-tsc/src/live/ContactFields.js.map +1 -0
  156. package/out-tsc/src/live/ContactNameFetch.js.map +1 -0
  157. package/out-tsc/src/{contacts → live}/ContactNotepad.js +1 -1
  158. package/out-tsc/src/{contacts → live}/ContactNotepad.js.map +1 -1
  159. package/out-tsc/src/{contacts → live}/ContactPending.js +1 -1
  160. package/out-tsc/src/live/ContactPending.js.map +1 -0
  161. package/out-tsc/src/live/ContactStoreElement.js.map +1 -0
  162. package/out-tsc/src/live/FieldManager.js.map +1 -0
  163. package/out-tsc/src/live/StartProgress.js.map +1 -0
  164. package/out-tsc/src/{chart → live}/TembaChart.js +5 -1
  165. package/out-tsc/src/live/TembaChart.js.map +1 -0
  166. package/out-tsc/src/locales/es.js +5 -5
  167. package/out-tsc/src/locales/es.js.map +1 -1
  168. package/out-tsc/src/locales/fr.js +5 -5
  169. package/out-tsc/src/locales/fr.js.map +1 -1
  170. package/out-tsc/src/locales/locale-codes.js +2 -11
  171. package/out-tsc/src/locales/locale-codes.js.map +1 -1
  172. package/out-tsc/src/locales/pt.js +5 -5
  173. package/out-tsc/src/locales/pt.js.map +1 -1
  174. package/out-tsc/src/store/AppState.js +54 -24
  175. package/out-tsc/src/store/AppState.js.map +1 -1
  176. package/out-tsc/src/store/Store.js +1 -1
  177. package/out-tsc/src/store/Store.js.map +1 -1
  178. package/out-tsc/src/{utils/index.js → utils.js} +22 -1
  179. package/out-tsc/src/utils.js.map +1 -0
  180. package/out-tsc/src/webchat/WebChat.js +1 -1
  181. package/out-tsc/src/webchat/WebChat.js.map +1 -1
  182. package/out-tsc/temba-components.js +2 -2
  183. package/out-tsc/temba-components.js.map +1 -1
  184. package/out-tsc/temba-modules.js +54 -54
  185. package/out-tsc/temba-modules.js.map +1 -1
  186. package/out-tsc/temba-webchat.js +2 -2
  187. package/out-tsc/temba-webchat.js.map +1 -1
  188. package/out-tsc/test/temba-alert.test.js +1 -1
  189. package/out-tsc/test/temba-alert.test.js.map +1 -1
  190. package/out-tsc/test/temba-appstate-language.test.js +90 -0
  191. package/out-tsc/test/temba-appstate-language.test.js.map +1 -1
  192. package/out-tsc/test/temba-charcount.test.js.map +1 -1
  193. package/out-tsc/test/temba-chart.test.js +1 -1
  194. package/out-tsc/test/temba-chart.test.js.map +1 -1
  195. package/out-tsc/test/temba-checkbox.test.js.map +1 -1
  196. package/out-tsc/test/temba-color-picker.test.js +1 -1
  197. package/out-tsc/test/temba-color-picker.test.js.map +1 -1
  198. package/out-tsc/test/temba-completion.test.js +1 -1
  199. package/out-tsc/test/temba-completion.test.js.map +1 -1
  200. package/out-tsc/test/temba-compose.test.js +1 -1
  201. package/out-tsc/test/temba-compose.test.js.map +1 -1
  202. package/out-tsc/test/temba-contact-badges.test.js +1 -1
  203. package/out-tsc/test/temba-contact-badges.test.js.map +1 -1
  204. package/out-tsc/test/temba-contact-chat.test.js +3 -1
  205. package/out-tsc/test/temba-contact-chat.test.js.map +1 -1
  206. package/out-tsc/test/temba-contact-details.test.js +1 -1
  207. package/out-tsc/test/temba-contact-details.test.js.map +1 -1
  208. package/out-tsc/test/temba-contact-fields.test.js +1 -1
  209. package/out-tsc/test/temba-contact-fields.test.js.map +1 -1
  210. package/out-tsc/test/temba-contact-search.test.js +1 -1
  211. package/out-tsc/test/temba-contact-search.test.js.map +1 -1
  212. package/out-tsc/test/temba-date.test.js +5 -1
  213. package/out-tsc/test/temba-date.test.js.map +1 -1
  214. package/out-tsc/test/temba-datepicker.test.js +1 -1
  215. package/out-tsc/test/temba-datepicker.test.js.map +1 -1
  216. package/out-tsc/test/temba-dialog.test.js +1 -1
  217. package/out-tsc/test/temba-dialog.test.js.map +1 -1
  218. package/out-tsc/test/temba-dropdown.test.js +1 -1
  219. package/out-tsc/test/temba-dropdown.test.js.map +1 -1
  220. package/out-tsc/test/temba-excellent-helpers.test.js +316 -0
  221. package/out-tsc/test/temba-excellent-helpers.test.js.map +1 -0
  222. package/out-tsc/test/temba-field-manager.test.js.map +1 -1
  223. package/out-tsc/test/temba-flow-editor-node.test.js +414 -1
  224. package/out-tsc/test/temba-flow-editor-node.test.js.map +1 -1
  225. package/out-tsc/test/temba-flow-editor.test.js +185 -0
  226. package/out-tsc/test/temba-flow-editor.test.js.map +1 -1
  227. package/out-tsc/test/temba-flow-plumber-connections.test.js +113 -0
  228. package/out-tsc/test/temba-flow-plumber-connections.test.js.map +1 -0
  229. package/out-tsc/test/temba-flow-plumber.test.js +73 -93
  230. package/out-tsc/test/temba-flow-plumber.test.js.map +1 -1
  231. package/out-tsc/test/temba-flow-render.test.js +624 -1
  232. package/out-tsc/test/temba-flow-render.test.js.map +1 -1
  233. package/out-tsc/test/temba-flow-self-routing.test.js +172 -0
  234. package/out-tsc/test/temba-flow-self-routing.test.js.map +1 -0
  235. package/out-tsc/test/temba-formfield.test.js.map +1 -1
  236. package/out-tsc/test/temba-icon.test.js +1 -1
  237. package/out-tsc/test/temba-icon.test.js.map +1 -1
  238. package/out-tsc/test/temba-integration-markdown.test.js.map +1 -1
  239. package/out-tsc/test/temba-label.test.js +1 -1
  240. package/out-tsc/test/temba-label.test.js.map +1 -1
  241. package/out-tsc/test/temba-lightbox.test.js +1 -1
  242. package/out-tsc/test/temba-lightbox.test.js.map +1 -1
  243. package/out-tsc/test/temba-markdown.test.js +127 -0
  244. package/out-tsc/test/temba-markdown.test.js.map +1 -0
  245. package/out-tsc/test/temba-menu.test.js +1 -1
  246. package/out-tsc/test/temba-menu.test.js.map +1 -1
  247. package/out-tsc/test/temba-modax.test.js +1 -1
  248. package/out-tsc/test/temba-modax.test.js.map +1 -1
  249. package/out-tsc/test/temba-modules.test.js +47 -0
  250. package/out-tsc/test/temba-modules.test.js.map +1 -0
  251. package/out-tsc/test/temba-omnibox.test.js +1 -1
  252. package/out-tsc/test/temba-omnibox.test.js.map +1 -1
  253. package/out-tsc/test/temba-options.test.js.map +1 -1
  254. package/out-tsc/test/temba-range-picker.test.js +9 -2
  255. package/out-tsc/test/temba-range-picker.test.js.map +1 -1
  256. package/out-tsc/test/temba-rapid-element.test.js +273 -0
  257. package/out-tsc/test/temba-rapid-element.test.js.map +1 -0
  258. package/out-tsc/test/temba-resize-element.test.js +85 -0
  259. package/out-tsc/test/temba-resize-element.test.js.map +1 -0
  260. package/out-tsc/test/temba-select.test.js +2 -2
  261. package/out-tsc/test/temba-select.test.js.map +1 -1
  262. package/out-tsc/test/temba-slider.test.js.map +1 -1
  263. package/out-tsc/test/temba-sticky-note.test.js +194 -0
  264. package/out-tsc/test/temba-sticky-note.test.js.map +1 -0
  265. package/out-tsc/test/temba-template-editor.test.js.map +1 -1
  266. package/out-tsc/test/temba-textinput.test.js +1 -1
  267. package/out-tsc/test/temba-textinput.test.js.map +1 -1
  268. package/out-tsc/test/temba-tip.test.js +1 -1
  269. package/out-tsc/test/temba-tip.test.js.map +1 -1
  270. package/out-tsc/test/temba-toast.test.js +1 -1
  271. package/out-tsc/test/temba-toast.test.js.map +1 -1
  272. package/out-tsc/test/temba-utils-index.test.js +1 -1
  273. package/out-tsc/test/temba-utils-index.test.js.map +1 -1
  274. package/out-tsc/test/temba-utils-uuid.test.js +38 -0
  275. package/out-tsc/test/temba-utils-uuid.test.js.map +1 -0
  276. package/out-tsc/test/temba-webchat.test.js +28 -12
  277. package/out-tsc/test/temba-webchat.test.js.map +1 -1
  278. package/out-tsc/test/utils.test.js +2 -6
  279. package/out-tsc/test/utils.test.js.map +1 -1
  280. package/package.json +18 -9
  281. package/rollup.components.mjs +1 -1
  282. package/screenshots/truth/datepicker/range-picker-all.png +0 -0
  283. package/screenshots/truth/datepicker/range-picker-button-states.png +0 -0
  284. package/screenshots/truth/datepicker/range-picker-default.png +0 -0
  285. package/screenshots/truth/datepicker/range-picker-editing-start.png +0 -0
  286. package/screenshots/truth/datepicker/range-picker-initial-values.png +0 -0
  287. package/screenshots/truth/datepicker/range-picker-week.png +0 -0
  288. package/screenshots/truth/datepicker/range-picker-year.png +0 -0
  289. package/screenshots/truth/sticky-note/blue-color.png +0 -0
  290. package/screenshots/truth/sticky-note/blue.png +0 -0
  291. package/screenshots/truth/sticky-note/color-picker-expanded.png +0 -0
  292. package/screenshots/truth/sticky-note/default.png +0 -0
  293. package/screenshots/truth/sticky-note/gray-color.png +0 -0
  294. package/screenshots/truth/sticky-note/gray.png +0 -0
  295. package/screenshots/truth/sticky-note/green-color.png +0 -0
  296. package/screenshots/truth/sticky-note/green.png +0 -0
  297. package/screenshots/truth/sticky-note/pink-color.png +0 -0
  298. package/screenshots/truth/sticky-note/pink.png +0 -0
  299. package/screenshots/truth/sticky-note/yellow-color.png +0 -0
  300. package/screenshots/truth/sticky-note/yellow.png +0 -0
  301. package/src/{charcount → display}/CharCount.ts +164 -2
  302. package/src/{vectoricon/VectorIcon.ts → display/Icon.ts} +1 -1
  303. package/src/{leafletmap → display}/LeafletMap.ts +19 -1
  304. package/src/{thumbnail → display}/Thumbnail.ts +1 -1
  305. package/src/{tip → display}/Tip.ts +1 -2
  306. package/src/{contacts/events.ts → events.ts} +1 -64
  307. package/src/flow/Editor.ts +655 -165
  308. package/src/flow/EditorNode.ts +337 -22
  309. package/src/flow/Plumber.ts +186 -79
  310. package/src/flow/StickyNote.ts +165 -9
  311. package/src/flow/config.ts +114 -18
  312. package/src/flow/render.ts +398 -11
  313. package/src/{checkbox → form}/Checkbox.ts +2 -2
  314. package/src/{colorpicker → form}/ColorPicker.ts +2 -2
  315. package/src/{completion → form}/Completion.ts +3 -3
  316. package/src/{compose → form}/Compose.ts +7 -7
  317. package/src/{contactsearch → form}/ContactSearch.ts +6 -6
  318. package/src/{datepicker → form}/DatePicker.ts +1 -1
  319. package/src/{FormElement.ts → form/FormElement.ts} +1 -1
  320. package/src/{imagepicker → form}/ImagePicker.ts +2 -2
  321. package/src/{mediapicker → form}/MediaPicker.ts +1 -1
  322. package/src/{datepicker → form}/RangePicker.ts +3 -2
  323. package/src/{slider → form}/TembaSlider.ts +1 -1
  324. package/src/{templates → form}/TemplateEditor.ts +2 -2
  325. package/src/{textinput → form}/TextInput.ts +5 -5
  326. package/src/{omnibox → form/select}/Omnibox.ts +2 -2
  327. package/src/{select → form/select}/PopupSelect.ts +1 -1
  328. package/src/{select → form/select}/Select.ts +124 -126
  329. package/src/{select → form/select}/UserSelect.ts +1 -1
  330. package/src/{select → form/select}/WorkspaceSelect.ts +1 -1
  331. package/src/interfaces.ts +2 -1
  332. package/src/{dialog → layout}/Dialog.ts +1 -1
  333. package/src/list/NotificationList.ts +2 -2
  334. package/src/list/RunList.ts +3 -3
  335. package/src/list/ShortcutList.ts +1 -1
  336. package/src/list/TembaMenu.ts +2 -2
  337. package/src/list/TicketList.ts +1 -1
  338. package/src/{aliaseditor → live}/AliasEditor.ts +3 -3
  339. package/src/{contacts → live}/ContactBadges.ts +1 -1
  340. package/src/{contacts → live}/ContactChat.ts +118 -8
  341. package/src/{contacts → live}/ContactDetails.ts +1 -1
  342. package/src/{contacts → live}/ContactFieldEditor.ts +4 -4
  343. package/src/{contacts → live}/ContactFields.ts +1 -1
  344. package/src/{contacts → live}/ContactNotepad.ts +1 -1
  345. package/src/{contacts → live}/ContactPending.ts +1 -1
  346. package/src/{chart → live}/TembaChart.ts +5 -2
  347. package/src/locales/es.ts +13 -18
  348. package/src/locales/fr.ts +13 -18
  349. package/src/locales/locale-codes.ts +2 -11
  350. package/src/locales/pt.ts +13 -18
  351. package/src/store/AppState.ts +75 -29
  352. package/src/store/Store.ts +1 -1
  353. package/src/store/flow-definition.d.ts +125 -0
  354. package/src/{utils/index.ts → utils.ts} +26 -10
  355. package/src/webchat/WebChat.ts +1 -1
  356. package/static/css/temba-components.css +1 -0
  357. package/svg.js +1 -4
  358. package/temba-components.ts +2 -2
  359. package/temba-modules.ts +54 -54
  360. package/temba-webchat.ts +2 -2
  361. package/test/temba-alert.test.ts +1 -1
  362. package/test/temba-appstate-language.test.ts +108 -0
  363. package/test/temba-charcount.test.ts +1 -1
  364. package/test/temba-chart.test.ts +1 -1
  365. package/test/temba-checkbox.test.ts +1 -1
  366. package/test/temba-color-picker.test.ts +1 -1
  367. package/test/temba-completion.test.ts +1 -1
  368. package/test/temba-compose.test.ts +1 -1
  369. package/test/temba-contact-badges.test.ts +1 -1
  370. package/test/temba-contact-chat.test.ts +6 -4
  371. package/test/temba-contact-details.test.ts +1 -1
  372. package/test/temba-contact-fields.test.ts +1 -1
  373. package/test/temba-contact-search.test.ts +2 -2
  374. package/test/temba-date.test.ts +8 -3
  375. package/test/temba-datepicker.test.ts +1 -1
  376. package/test/temba-dialog.test.ts +1 -1
  377. package/test/temba-dropdown.test.ts +1 -1
  378. package/test/temba-excellent-helpers.test.ts +417 -0
  379. package/test/temba-field-manager.test.ts +2 -2
  380. package/test/temba-flow-editor-node.test.ts +536 -1
  381. package/test/temba-flow-editor.test.ts +224 -0
  382. package/test/temba-flow-editor.test.ts.backup +563 -0
  383. package/test/temba-flow-plumber-connections.test.ts +142 -0
  384. package/test/temba-flow-plumber.test.ts +83 -120
  385. package/test/temba-flow-render.test.ts +787 -4
  386. package/test/temba-flow-self-routing.test.ts +215 -0
  387. package/test/temba-formfield.test.ts +1 -1
  388. package/test/temba-icon.test.ts +1 -1
  389. package/test/temba-integration-markdown.test.ts +1 -1
  390. package/test/temba-label.test.ts +1 -1
  391. package/test/temba-lightbox.test.ts +1 -1
  392. package/test/temba-markdown.test.ts +162 -0
  393. package/test/temba-menu.test.ts +1 -1
  394. package/test/temba-modax.test.ts +2 -2
  395. package/test/temba-modules.test.ts +56 -0
  396. package/test/temba-omnibox.test.ts +1 -1
  397. package/test/temba-options.test.ts +1 -1
  398. package/test/temba-range-picker.test.ts +17 -2
  399. package/test/temba-rapid-element.test.ts +341 -0
  400. package/test/temba-resize-element.test.ts +104 -0
  401. package/test/temba-select.test.ts +2 -2
  402. package/test/temba-slider.test.ts +1 -1
  403. package/test/temba-sticky-note.test.ts +281 -0
  404. package/test/temba-template-editor.test.ts +1 -1
  405. package/test/temba-textinput.test.ts +1 -1
  406. package/test/temba-tip.test.ts +1 -1
  407. package/test/temba-toast.test.ts +1 -1
  408. package/test/temba-utils-index.test.ts +1 -1
  409. package/test/temba-utils-index.test.ts.backup +1737 -0
  410. package/test/temba-utils-uuid.test.ts +48 -0
  411. package/test/temba-webchat.test.ts +30 -12
  412. package/test/utils.test.ts +5 -9
  413. package/web-dev-server.config.mjs +1 -1
  414. package/demo/alert/example.html +0 -65
  415. package/demo/button/example.html +0 -71
  416. package/demo/chart/horizontal-demo.html +0 -81
  417. package/demo/checkbox/example.html +0 -72
  418. package/demo/compose/example.html +0 -72
  419. package/demo/dropdown/example.html +0 -99
  420. package/demo/progress/example.html +0 -59
  421. package/demo/select/drag-and-drop.html +0 -142
  422. package/demo/select/example.html +0 -82
  423. package/demo/select/multi.html +0 -73
  424. package/demo/slider/example.html +0 -59
  425. package/demo/tabs/example.html +0 -91
  426. package/demo/textinput/example.html +0 -61
  427. package/out-tsc/src/FormElement.js.map +0 -1
  428. package/out-tsc/src/alert/Alert.js.map +0 -1
  429. package/out-tsc/src/aliaseditor/AliasEditor.js.map +0 -1
  430. package/out-tsc/src/anchor/Anchor.js.map +0 -1
  431. package/out-tsc/src/button/Button.js.map +0 -1
  432. package/out-tsc/src/charcount/CharCount.js.map +0 -1
  433. package/out-tsc/src/charcount/helpers.js +0 -159
  434. package/out-tsc/src/charcount/helpers.js.map +0 -1
  435. package/out-tsc/src/chart/TembaChart.js.map +0 -1
  436. package/out-tsc/src/chat/Chat.js.map +0 -1
  437. package/out-tsc/src/checkbox/Checkbox.js.map +0 -1
  438. package/out-tsc/src/colorpicker/ColorPicker.js.map +0 -1
  439. package/out-tsc/src/completion/Completion.js.map +0 -1
  440. package/out-tsc/src/completion/ExcellentParser.js.map +0 -1
  441. package/out-tsc/src/completion/helpers.js.map +0 -1
  442. package/out-tsc/src/compose/Compose.js.map +0 -1
  443. package/out-tsc/src/contacts/ContactBadges.js.map +0 -1
  444. package/out-tsc/src/contacts/ContactChat.js.map +0 -1
  445. package/out-tsc/src/contacts/ContactDetails.js.map +0 -1
  446. package/out-tsc/src/contacts/ContactFieldEditor.js.map +0 -1
  447. package/out-tsc/src/contacts/ContactFields.js.map +0 -1
  448. package/out-tsc/src/contacts/ContactName.js.map +0 -1
  449. package/out-tsc/src/contacts/ContactNameFetch.js.map +0 -1
  450. package/out-tsc/src/contacts/ContactPending.js.map +0 -1
  451. package/out-tsc/src/contacts/ContactStoreElement.js.map +0 -1
  452. package/out-tsc/src/contacts/ContactUrn.js.map +0 -1
  453. package/out-tsc/src/contacts/events.js +0 -65
  454. package/out-tsc/src/contacts/events.js.map +0 -1
  455. package/out-tsc/src/contacts/helpers.js +0 -77
  456. package/out-tsc/src/contacts/helpers.js.map +0 -1
  457. package/out-tsc/src/contactsearch/ContactSearch.js.map +0 -1
  458. package/out-tsc/src/date/TembaDate.js.map +0 -1
  459. package/out-tsc/src/datepicker/DatePicker.js.map +0 -1
  460. package/out-tsc/src/datepicker/RangePicker.js.map +0 -1
  461. package/out-tsc/src/dialog/Dialog.js.map +0 -1
  462. package/out-tsc/src/dropdown/Dropdown.js.map +0 -1
  463. package/out-tsc/src/fields/FieldManager.js.map +0 -1
  464. package/out-tsc/src/formfield/FormField.js.map +0 -1
  465. package/out-tsc/src/imagepicker/CroppieCSS.js.map +0 -1
  466. package/out-tsc/src/imagepicker/ImagePicker.js.map +0 -1
  467. package/out-tsc/src/label/Label.js.map +0 -1
  468. package/out-tsc/src/leafletmap/LeafletMap.js.map +0 -1
  469. package/out-tsc/src/leafletmap/helpers.js +0 -17
  470. package/out-tsc/src/leafletmap/helpers.js.map +0 -1
  471. package/out-tsc/src/lightbox/Lightbox.js.map +0 -1
  472. package/out-tsc/src/mask/Mask.js.map +0 -1
  473. package/out-tsc/src/mediapicker/MediaPicker.js.map +0 -1
  474. package/out-tsc/src/omnibox/Omnibox.js.map +0 -1
  475. package/out-tsc/src/options/helpers.js +0 -28
  476. package/out-tsc/src/options/helpers.js.map +0 -1
  477. package/out-tsc/src/progress/ProgressBar.js.map +0 -1
  478. package/out-tsc/src/progress/StartProgress.js.map +0 -1
  479. package/out-tsc/src/resizer/Resizer.js.map +0 -1
  480. package/out-tsc/src/select/PopupSelect.js.map +0 -1
  481. package/out-tsc/src/select/Select.js.map +0 -1
  482. package/out-tsc/src/select/UserSelect.js.map +0 -1
  483. package/out-tsc/src/select/WorkspaceSelect.js.map +0 -1
  484. package/out-tsc/src/select/helpers.js +0 -1
  485. package/out-tsc/src/select/helpers.js.map +0 -1
  486. package/out-tsc/src/shadowless/Shadowless.js +0 -33
  487. package/out-tsc/src/shadowless/Shadowless.js.map +0 -1
  488. package/out-tsc/src/slider/TembaSlider.js.map +0 -1
  489. package/out-tsc/src/sms/gsmsplitter.js.map +0 -1
  490. package/out-tsc/src/sms/gsmvalidator.js.map +0 -1
  491. package/out-tsc/src/sms/index.js.map +0 -1
  492. package/out-tsc/src/sms/unicodesplitter.js.map +0 -1
  493. package/out-tsc/src/tabpane/Tab.js.map +0 -1
  494. package/out-tsc/src/tabpane/TabPane.js.map +0 -1
  495. package/out-tsc/src/templates/TemplateEditor.js.map +0 -1
  496. package/out-tsc/src/textinput/TextInput.js.map +0 -1
  497. package/out-tsc/src/textinput/helpers.js +0 -12
  498. package/out-tsc/src/textinput/helpers.js.map +0 -1
  499. package/out-tsc/src/thumbnail/Thumbnail.js.map +0 -1
  500. package/out-tsc/src/tip/Tip.js.map +0 -1
  501. package/out-tsc/src/tip/helpers.js +0 -7
  502. package/out-tsc/src/tip/helpers.js.map +0 -1
  503. package/out-tsc/src/toast/Toast.js.map +0 -1
  504. package/out-tsc/src/user/TembaUser.js.map +0 -1
  505. package/out-tsc/src/utils/index.js.map +0 -1
  506. package/out-tsc/src/vectoricon/VectorIcon.js.map +0 -1
  507. package/out-tsc/src/vectoricon/index.js.map +0 -1
  508. package/src/charcount/helpers.ts +0 -162
  509. package/src/contacts/helpers.ts +0 -103
  510. package/src/leafletmap/helpers.ts +0 -18
  511. package/src/options/helpers.ts +0 -37
  512. package/src/select/helpers.ts +0 -0
  513. package/src/shadowless/Shadowless.ts +0 -32
  514. package/src/textinput/helpers.ts +0 -11
  515. package/src/tip/helpers.ts +0 -7
  516. /package/out-tsc/src/{alert → display}/Alert.js +0 -0
  517. /package/out-tsc/src/{anchor → display}/Anchor.js +0 -0
  518. /package/out-tsc/src/{button → display}/Button.js +0 -0
  519. /package/out-tsc/src/{chat → display}/Chat.js +0 -0
  520. /package/out-tsc/src/{contacts → display}/ContactName.js +0 -0
  521. /package/out-tsc/src/{contacts → display}/ContactUrn.js +0 -0
  522. /package/out-tsc/src/{dropdown → display}/Dropdown.js +0 -0
  523. /package/out-tsc/src/{label → display}/Label.js +0 -0
  524. /package/out-tsc/src/{lightbox → display}/Lightbox.js +0 -0
  525. /package/out-tsc/src/{loading → display}/Loading.js +0 -0
  526. /package/out-tsc/src/{options → display}/Options.js +0 -0
  527. /package/out-tsc/src/{progress → display}/ProgressBar.js +0 -0
  528. /package/out-tsc/src/{date → display}/TembaDate.js +0 -0
  529. /package/out-tsc/src/{user → display}/TembaUser.js +0 -0
  530. /package/out-tsc/src/{thumbnail → display}/Thumbnail.js +0 -0
  531. /package/out-tsc/src/{toast → display}/Toast.js +0 -0
  532. /package/out-tsc/src/{sms → display/sms}/gsmsplitter.js +0 -0
  533. /package/out-tsc/src/{sms → display/sms}/gsmvalidator.js +0 -0
  534. /package/out-tsc/src/{sms → display/sms}/index.js +0 -0
  535. /package/out-tsc/src/{sms → display/sms}/unicodesplitter.js +0 -0
  536. /package/out-tsc/src/{completion → excellent}/ExcellentParser.js +0 -0
  537. /package/out-tsc/src/{completion → excellent}/helpers.js +0 -0
  538. /package/out-tsc/src/{imagepicker → form}/CroppieCSS.js +0 -0
  539. /package/out-tsc/src/{formfield → form}/FormField.js +0 -0
  540. /package/out-tsc/src/{dialog → layout}/Dialog.js +0 -0
  541. /package/out-tsc/src/{mask → layout}/Mask.js +0 -0
  542. /package/out-tsc/src/{dialog → layout}/Modax.js +0 -0
  543. /package/out-tsc/src/{resizer → layout}/Resizer.js +0 -0
  544. /package/out-tsc/src/{tabpane → layout}/Tab.js +0 -0
  545. /package/out-tsc/src/{tabpane → layout}/TabPane.js +0 -0
  546. /package/out-tsc/src/{contacts → live}/ContactFields.js +0 -0
  547. /package/out-tsc/src/{contacts → live}/ContactNameFetch.js +0 -0
  548. /package/out-tsc/src/{contacts → live}/ContactStoreElement.js +0 -0
  549. /package/out-tsc/src/{fields → live}/FieldManager.js +0 -0
  550. /package/out-tsc/src/{progress → live}/StartProgress.js +0 -0
  551. /package/src/{vectoricon/index.ts → Icons.ts} +0 -0
  552. /package/src/{alert → display}/Alert.ts +0 -0
  553. /package/src/{anchor → display}/Anchor.ts +0 -0
  554. /package/src/{button → display}/Button.ts +0 -0
  555. /package/src/{chat → display}/Chat.ts +0 -0
  556. /package/src/{contacts → display}/ContactName.ts +0 -0
  557. /package/src/{contacts → display}/ContactUrn.ts +0 -0
  558. /package/src/{dropdown → display}/Dropdown.ts +0 -0
  559. /package/src/{label → display}/Label.ts +0 -0
  560. /package/src/{lightbox → display}/Lightbox.ts +0 -0
  561. /package/src/{loading → display}/Loading.ts +0 -0
  562. /package/src/{options → display}/Options.ts +0 -0
  563. /package/src/{progress → display}/ProgressBar.ts +0 -0
  564. /package/src/{date → display}/TembaDate.ts +0 -0
  565. /package/src/{user → display}/TembaUser.ts +0 -0
  566. /package/src/{toast → display}/Toast.ts +0 -0
  567. /package/src/{sms → display/sms}/gsmsplitter.ts +0 -0
  568. /package/src/{sms → display/sms}/gsmvalidator.ts +0 -0
  569. /package/src/{sms → display/sms}/index.ts +0 -0
  570. /package/src/{sms → display/sms}/unicodesplitter.ts +0 -0
  571. /package/src/{completion → excellent}/ExcellentParser.ts +0 -0
  572. /package/src/{completion → excellent}/helpers.ts +0 -0
  573. /package/src/{imagepicker → form}/CroppieCSS.ts +0 -0
  574. /package/src/{formfield → form}/FormField.ts +0 -0
  575. /package/src/{mask → layout}/Mask.ts +0 -0
  576. /package/src/{dialog → layout}/Modax.ts +0 -0
  577. /package/src/{resizer → layout}/Resizer.ts +0 -0
  578. /package/src/{tabpane → layout}/Tab.ts +0 -0
  579. /package/src/{tabpane → layout}/TabPane.ts +0 -0
  580. /package/src/{contacts → live}/ContactNameFetch.ts +0 -0
  581. /package/src/{contacts → live}/ContactStoreElement.ts +0 -0
  582. /package/src/{fields → live}/FieldManager.ts +0 -0
  583. /package/src/{progress → live}/StartProgress.ts +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"EditorNode.js","sourceRoot":"","sources":["../../../src/flow/EditorNode.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, PropertyValueMap, TemplateResult } from 'lit';\nimport { EDITOR_CONFIG, UIConfig } from './config';\nimport { Action, Exit, Node, NodeUI, Router } from '../store/flow-definition';\nimport { property } from 'lit/decorators.js';\nimport { RapidElement } from '../RapidElement';\nimport { getClasses } from '../utils';\nimport { Plumber } from './Plumber';\nimport { getStore } from '../store/Store';\n\nexport class EditorNode extends RapidElement {\n createRenderRoot() {\n return this;\n }\n\n @property({ type: Object })\n private plumber: Plumber;\n\n @property({ type: Object })\n private node: Node;\n\n @property({ type: Object })\n private ui: NodeUI;\n\n static get styles() {\n return css`\n\n .node {\n background-color: #fff;\n box-shadow: 0 0 5px rgba(0, 0, 0, 0.2);\n min-width: 200px;\n border-radius: calc(var(--curvature) * 1.5);\n overflow: hidden;\n color: #333;\n cursor: move;\n user-select: none;\n\n }\n\n .node:hover {\n box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);\n }\n\n .node.dragging {\n box-shadow: 0 5px 15px rgba(0, 0, 0, 0.4);\n transform: scale(1.02);\n z-index: 1000;\n }\n \n .action {\n max-width: 200px;\n position: relative;\n }\n\n .action.sortable {\n display: flex;\n align-items: stretch;\n }\n\n .action .action-content {\n flex-grow: 1;\n display: flex;\n flex-direction: column;\n }\n\n .action .body {\n padding: 1em;\n }\n\n .action .drag-handle {\n opacity: 0;\n transition: all 200ms ease-in-out;\n cursor: move;\n background: rgba(0, 0, 0, 0.02);\n max-width:0px;\n position: absolute;\n }\n\n .action:hover .drag-handle {\n opacity: 0.5;\n padding: 0.25em;\n max-width: 20px;\n }\n\n .action .drag-handle:hover {\n opacity: 1;\n \n }\n\n .action .title,\n .router .title {\n display: flex;\n color: #fff;\n padding: 5px 1px;\n text-align: center;\n font-size: 1em;\n font-weight: normal;\n\n }\n\n .title .name {\n flex-grow: 1;\n }\n\n .quick-replies {\n margin-top: 0.5em;\n }\n\n .quick-reply {\n background-color: #f0f0f0;\n border: 1px solid #e0e0e0;\n border-radius: calc(var(--curvature) * 1.5);\n padding: 0.2em 1em;\n display: inline-block;\n font-size: 0.8em;\n margin: 0.2em;\n }\n\n .categories {\n display: flex;\n flex-direction: row;\n\n }\n\n .category {\n margin:-1px -0.5px;\n border: 1px solid #f3f3f3;\n padding: 0.75em;\n flex-grow:1;\n text-align: center;\n }\n\n .action-exits {\n padding-bottom: 0.75em;\n margin-top: -0.75em;\n }\n\n .category .title {\n font-weight: normal;\n font-size: 1em;\n }\n\n .router .body {\n padding: 0.75em;\n }\n\n .result-name {\n font-weight: bold;\n display: inline-block;\n }\n \n .exit {\n padding-top: 10px;\n margin-bottom: -10px;\n }\n }`;\n }\n\n constructor() {\n super();\n this.handleActionOrderChanged = this.handleActionOrderChanged.bind(this);\n }\n\n protected updated(\n changes: PropertyValueMap<any> | Map<PropertyKey, unknown>\n ): void {\n super.updated(changes);\n if (changes.has('node')) {\n // make our initial connections\n if (changes.get('node') === undefined) {\n // this.plumber.makeTarget(this.node.uuid);\n for (const exit of this.node.exits) {\n if (!exit.destination_uuid) {\n this.plumber.makeSource(exit.uuid);\n } else {\n this.plumber.connectIds(exit.uuid, exit.destination_uuid);\n }\n }\n }\n\n const ele = this.parentElement;\n const rect = ele.getBoundingClientRect();\n\n getStore()\n ?.getState()\n .expandCanvas(\n this.ui.position.left + rect.width,\n this.ui.position.top + rect.height\n );\n }\n }\n\n private handleActionOrderChanged(event: CustomEvent) {\n const [fromIdx, toIdx] = event.detail.swap;\n\n // swap our actions\n const newActions = [...this.node.actions];\n const movedAction = newActions.splice(fromIdx, 1)[0];\n newActions.splice(toIdx, 0, movedAction);\n\n // udate our internal reprensentation, this isn't strictly necessary\n // since the editor will update us from it's definition subscription\n // but it makes testing a lot easier\n this.node = { ...this.node, actions: newActions };\n\n getStore()\n ?.getState()\n .updateNode(this.node.uuid, { ...this.node, actions: newActions });\n }\n\n private renderTitle(config: UIConfig) {\n return html`<div class=\"title\" style=\"background:${config.color}\">\n ${this.node?.actions?.length > 1\n ? html`<temba-icon class=\"drag-handle\" name=\"sort\"></temba-icon>`\n : null}\n\n <div class=\"name\">${config.name}</div>\n </div>`;\n }\n\n private renderAction(node: Node, action: Action, index: number) {\n const config = EDITOR_CONFIG[action.type];\n\n if (config) {\n return html`<div\n class=\"action sortable ${action.type}\"\n id=\"action-${index}\"\n >\n <div class=\"action-content\">\n ${this.renderTitle(config)}\n <div class=\"body\">\n ${config.render\n ? config.render(node, action)\n : html`<pre>${action.type}</pre>`}\n </div>\n </div>\n </div>`;\n }\n return html`<div class=\"action sortable\" id=\"action-${index}\">\n ${action.type}\n </div>`;\n }\n\n private renderRouter(router: Router, ui: NodeUI) {\n const config = EDITOR_CONFIG[ui.type];\n if (config) {\n return html`<div class=\"router\">\n ${this.renderTitle(config)}\n ${router.result_name\n ? html`<div class=\"body\">\n Save as\n <div class=\"result-name\">${router.result_name}</div>\n </div>`\n : null}\n </div>`;\n }\n }\n\n private renderCategories(node: Node) {\n if (!node.router || !node.router.categories) {\n return null;\n }\n const categories = node.router.categories.map((category) => {\n const exit = node.exits.find(\n (exit: Exit) => exit.uuid == category.exit_uuid\n );\n\n return html`<div class=\"category\">\n <div class=\"title\">${category.name}</div>\n ${this.renderExit(exit)}\n </div>`;\n });\n\n return html`<div class=\"categories\">${categories}</div>`;\n }\n\n private renderExit(exit: Exit): TemplateResult {\n return html`<div\n id=\"${exit.uuid}\"\n class=${getClasses({\n exit: true,\n connected: !!exit.destination_uuid\n })}\n ></div>`;\n }\n\n public render() {\n if (!this.node || !this.ui) {\n return html`<div class=\"node\">Loading...</div>`;\n }\n\n return html`\n <div\n id=\"${this.node.uuid}\"\n class=\"node\"\n style=\"left:${this.ui.position.left}px;top:${this.ui.position.top}px\"\n >\n ${this.node.actions.length > 0\n ? html`<temba-sortable-list\n dragHandle=\"drag-handle\"\n @temba-order-changed=\"${this.handleActionOrderChanged}\"\n >\n ${this.node.actions.map((actionSpec, index) => {\n return this.renderAction(this.node, actionSpec, index);\n })}\n </temba-sortable-list>`\n : ''}\n ${this.node.router\n ? html` ${this.renderRouter(this.node.router, this.ui)}\n ${this.renderCategories(this.node)}`\n : html`<div class=\"action-exits\">\n ${this.node.exits.map((exit) => {\n return this.renderExit(exit);\n })}\n </div>`}\n </div>\n `;\n }\n}\n"]}
1
+ {"version":3,"file":"EditorNode.js","sourceRoot":"","sources":["../../../src/flow/EditorNode.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAoC,MAAM,KAAK,CAAC;AAClE,OAAO,EAAE,aAAa,EAAY,MAAM,UAAU,CAAC;AAEnD,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAEtC,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD,MAAM,OAAO,UAAW,SAAQ,YAAY;IAC1C,gBAAgB;QACd,OAAO,IAAI,CAAC;IACd,CAAC;IAuBD,MAAM,KAAK,MAAM;QACf,OAAO,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAoPV,CAAC;IACH,CAAC;IAED;QACE,KAAK,EAAE,CAAC;QArQV,2CAA2C;QACnC,wBAAmB,GAAwB,IAAI,GAAG,EAAE,CAAC;QAE7D,mDAAmD;QAC3C,sBAAiB,GAAgB,IAAI,GAAG,EAAE,CAAC;QAEnD,6CAA6C;QACrC,0BAAqB,GAAwB,IAAI,GAAG,EAAE,CAAC;QAE/D,qDAAqD;QAC7C,wBAAmB,GAAgB,IAAI,GAAG,EAAE,CAAC;QA4PnD,IAAI,CAAC,wBAAwB,GAAG,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3E,CAAC;IAES,OAAO,CACf,OAA0D;;QAE1D,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACvB,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACxB,+BAA+B;YAC/B,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,SAAS,EAAE,CAAC;gBACtC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;oBACnC,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC;wBAC3B,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBACrC,CAAC;yBAAM,CAAC;wBACN,IAAI,CAAC,OAAO,CAAC,UAAU,CACrB,IAAI,CAAC,IAAI,CAAC,IAAI,EACd,IAAI,CAAC,IAAI,EACT,IAAI,CAAC,gBAAgB,CACtB,CAAC;oBACJ,CAAC;gBACH,CAAC;YACH,CAAC;YAED,MAAM,GAAG,GAAG,IAAI,CAAC,aAAa,CAAC;YAC/B,MAAM,IAAI,GAAG,GAAG,CAAC,qBAAqB,EAAE,CAAC;YAEzC,MAAA,QAAQ,EAAE,0CACN,QAAQ,GACT,YAAY,CACX,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,EAClC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,CACnC,CAAC;QACN,CAAC;IACH,CAAC;IAED,oBAAoB;QAClB,0DAA0D;QAC1D,KAAK,CAAC,oBAAoB,EAAE,CAAC;QAE7B,0CAA0C;QAC1C,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE;YAC7C,YAAY,CAAC,SAAS,CAAC,CAAC;QAC1B,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,mBAAmB,CAAC,KAAK,EAAE,CAAC;QAEjC,4CAA4C;QAC5C,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE;YAC/C,YAAY,CAAC,SAAS,CAAC,CAAC;QAC1B,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,qBAAqB,CAAC,KAAK,EAAE,CAAC;QAEnC,2BAA2B;QAC3B,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,CAAC;QAC/B,IAAI,CAAC,mBAAmB,CAAC,KAAK,EAAE,CAAC;IACnC,CAAC;IAEO,eAAe,CAAC,KAAiB,EAAE,IAAU;QACnD,KAAK,CAAC,cAAc,EAAE,CAAC;QACvB,KAAK,CAAC,eAAe,EAAE,CAAC;QAExB,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC;QAEzB,uCAAuC;QACvC,IAAI,CAAC,IAAI,CAAC,gBAAgB;YAAE,OAAO;QAEnC,mEAAmE;QACnE,IAAI,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACvC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;YAC1B,OAAO;QACT,CAAC;QAED,yBAAyB;QACzB,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACnC,IAAI,CAAC,aAAa,EAAE,CAAC;QAErB,uCAAuC;QACvC,IAAI,CAAC,OAAO,CAAC,0BAA0B,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAEtD,2CAA2C;QAC3C,IAAI,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACzC,YAAY,CAAC,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;QACrD,CAAC;QAED,gDAAgD;QAChD,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE;YACvC,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YACtC,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAExC,uCAAuC;YACvC,IAAI,CAAC,OAAO,CAAC,0BAA0B,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;YAEvD,IAAI,CAAC,aAAa,EAAE,CAAC;QACvB,CAAC,EAAE,IAAI,CAAC,CAAC;QAET,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAClD,CAAC;IAEO,cAAc,CAAC,IAAU;;QAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC;QAEzB,qBAAqB;QACrB,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAEtC,4FAA4F;QAC5F,8DAA8D;QAC9D,IAAI,CAAC,OAAO,CAAC,0BAA0B,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAEvD,oBAAoB;QACpB,IAAI,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACzC,YAAY,CAAC,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;YACnD,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC1C,CAAC;QAED,gCAAgC;QAChC,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC;QAE1C,6BAA6B;QAC7B,MAAM,WAAW,GAAG,EAAE,GAAG,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,CAAC;QACxD,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAC7C,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CACpC,CAAC;QAEF,kBAAkB;QAClB,MAAM,WAAW,GAAG,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC;QAC1D,MAAA,QAAQ,EAAE,0CAAE,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAE/D,oCAAoC;QACpC,IAAI,CAAC,aAAa,EAAE,CAAC;IACvB,CAAC;IAEO,uBAAuB,CAC7B,KAAiB,EACjB,MAAc,EACd,KAAa;QAEb,KAAK,CAAC,cAAc,EAAE,CAAC;QACvB,KAAK,CAAC,eAAe,EAAE,CAAC;QAExB,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC;QAE7B,kEAAkE;QAClE,IAAI,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC3C,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;YACjC,OAAO;QACT,CAAC;QAED,yBAAyB;QACzB,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACvC,IAAI,CAAC,aAAa,EAAE,CAAC;QAErB,6CAA6C;QAC7C,IAAI,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC7C,YAAY,CAAC,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC;QACzD,CAAC;QAED,gDAAgD;QAChD,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE;YACvC,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC1C,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC5C,IAAI,CAAC,aAAa,EAAE,CAAC;QACvB,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,+BAA+B;QAEzC,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IACtD,CAAC;IAED,6DAA6D;IACrD,YAAY,CAAC,MAAc,EAAE,MAAc;;QACjD,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC;QAE7B,qBAAqB;QACrB,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAE1C,oBAAoB;QACpB,IAAI,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC7C,YAAY,CAAC,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC;YACvD,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC9C,CAAC;QAED,kCAAkC;QAClC,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;QAE5E,+CAA+C;QAC/C,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChC,IAAI,CAAC,eAAe,CAAC,eAAe,CAAC,WAAW,EAAE;gBAChD,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI;aACrB,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,yCAAyC;YACzC,MAAM,WAAW,GAAG,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC;YAC9D,MAAA,QAAQ,EAAE,0CAAE,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;YAE/D,oCAAoC;YACpC,IAAI,CAAC,aAAa,EAAE,CAAC;QACvB,CAAC;IACH,CAAC;IAEO,wBAAwB,CAAC,KAAkB;;QACjD,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC;QAE3C,mBAAmB;QACnB,MAAM,UAAU,GAAG,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC1C,MAAM,WAAW,GAAG,UAAU,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACrD,UAAU,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,EAAE,WAAW,CAAC,CAAC;QAEzC,oEAAoE;QACpE,oEAAoE;QACpE,oCAAoC;QACpC,IAAI,CAAC,IAAI,GAAG,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC;QAElD,MAAA,QAAQ,EAAE,0CACN,QAAQ,GACT,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;IACvE,CAAC;IAEO,WAAW,CAAC,MAAgB,EAAE,aAAsB,KAAK;;QAC/D,OAAO,IAAI,CAAA,wCAAwC,MAAM,CAAC,KAAK;QAC3D,CAAA,MAAA,MAAA,IAAI,CAAC,IAAI,0CAAE,OAAO,0CAAE,MAAM,IAAG,CAAC;YAC9B,CAAC,CAAC,IAAI,CAAA,2DAA2D;YACjE,CAAC,CAAC,IAAI;;0BAEY,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI;WACnD,CAAC;IACV,CAAC;IAEO,YAAY,CAAC,IAAU,EAAE,MAAc,EAAE,KAAa;QAC5D,MAAM,MAAM,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC1C,MAAM,UAAU,GAAG,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAE7D,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,IAAI,CAAA;iCACgB,MAAM,CAAC,IAAI,IAAI,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE;qBACvD,KAAK;;;;mBAIP,CAAC,CAAa,EAAE,EAAE,CACzB,IAAI,CAAC,uBAAuB,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC;;;;;;YAM9C,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC;;cAElC,MAAM,CAAC,MAAM;gBACb,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC;gBAC7B,CAAC,CAAC,IAAI,CAAA,QAAQ,MAAM,CAAC,IAAI,QAAQ;;;aAGlC,CAAC;QACV,CAAC;QACD,OAAO,IAAI,CAAA;+BACgB,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE;mBACxC,KAAK;;;;iBAIP,CAAC,CAAa,EAAE,EAAE,CACzB,IAAI,CAAC,uBAAuB,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC;;;;;QAKhD,MAAM,CAAC,IAAI;WACR,CAAC;IACV,CAAC;IAEO,YAAY,CAAC,MAAc,EAAE,EAAU;QAC7C,MAAM,MAAM,GAAG,aAAa,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;QACtC,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,IAAI,CAAA;UACP,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC;UAC/B,MAAM,CAAC,WAAW;gBAClB,CAAC,CAAC,IAAI,CAAA;;yCAEyB,MAAM,CAAC,WAAW;mBACxC;gBACT,CAAC,CAAC,IAAI;aACH,CAAC;QACV,CAAC;IACH,CAAC;IAEO,gBAAgB,CAAC,IAAU;QACjC,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;YAC5C,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE;YACzD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAC1B,CAAC,IAAU,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,IAAI,QAAQ,CAAC,SAAS,CAChD,CAAC;YAEF,OAAO,IAAI,CAAA;6BACY,QAAQ,CAAC,IAAI;UAChC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;aAClB,CAAC;QACV,CAAC,CAAC,CAAC;QAEH,OAAO,IAAI,CAAA,2BAA2B,UAAU,QAAQ,CAAC;IAC3D,CAAC;IAEO,UAAU,CAAC,IAAU;QAC3B,OAAO,IAAI,CAAA;;cAED,IAAI,CAAC,IAAI;gBACP,UAAU,CAAC;YACjB,IAAI,EAAE,IAAI;YACV,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,gBAAgB;YAClC,QAAQ,EAAE,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC;SAChD,CAAC;iBACO,CAAC,CAAa,EAAE,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,EAAE,IAAI,CAAC;;WAEtD,CAAC;IACV,CAAC;IAEM,MAAM;QACX,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;YAC3B,OAAO,IAAI,CAAA,oCAAoC,CAAC;QAClD,CAAC;QAED,OAAO,IAAI,CAAA;;cAED,IAAI,CAAC,IAAI,CAAC,IAAI;;sBAEN,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,UAAU,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG;;UAE/D,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC;YAC5B,CAAC,CAAC,IAAI,CAAA;;sCAEsB,IAAI,CAAC,wBAAwB;;gBAEnD,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,KAAK,EAAE,EAAE;gBAC5C,OAAO,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC;YACzD,CAAC,CAAC;mCACmB;YACzB,CAAC,CAAC,EAAE;UACJ,IAAI,CAAC,IAAI,CAAC,MAAM;YAChB,CAAC,CAAC,IAAI,CAAA,IAAI,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC;cAClD,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YACtC,CAAC,CAAC,IAAI,CAAA;gBACA,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;gBAC7B,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YAC/B,CAAC,CAAC;mBACG;;KAEd,CAAC;IACJ,CAAC;CACF;AAxmBS;IADP,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;2CACF;AAGjB;IADP,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;wCACR;AAGX;IADP,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;sCACR","sourcesContent":["import { css, html, PropertyValueMap, TemplateResult } from 'lit';\nimport { EDITOR_CONFIG, UIConfig } from './config';\nimport { Action, Exit, Node, NodeUI, Router } from '../store/flow-definition';\nimport { property } from 'lit/decorators.js';\nimport { RapidElement } from '../RapidElement';\nimport { getClasses } from '../utils';\nimport { Plumber } from './Plumber';\nimport { getStore } from '../store/Store';\nimport { CustomEventType } from '../interfaces';\n\nexport class EditorNode extends RapidElement {\n createRenderRoot() {\n return this;\n }\n\n @property({ type: Object })\n private plumber: Plumber;\n\n @property({ type: Object })\n private node: Node;\n\n @property({ type: Object })\n private ui: NodeUI;\n\n // Track exits that are in \"removing\" state\n private exitRemovalTimeouts: Map<string, number> = new Map();\n\n // Set of exit UUIDs that are in the removing state\n private exitRemovingState: Set<string> = new Set();\n\n // Track actions that are in \"removing\" state\n private actionRemovalTimeouts: Map<string, number> = new Map();\n\n // Set of action UUIDs that are in the removing state\n private actionRemovingState: Set<string> = new Set();\n\n static get styles() {\n return css`\n\n .node {\n background-color: #fff;\n box-shadow: 0 0 5px rgba(0, 0, 0, 0.2);\n min-width: 200px;\n border-radius: var(--curvature);\n \n color: #333;\n cursor: move;\n user-select: none;\n\n }\n\n .node:hover {\n box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);\n }\n\n .node.dragging {\n box-shadow: 0 5px 15px rgba(0, 0, 0, 0.4);\n transform: scale(1.02);\n z-index: 1000;\n }\n\n .action {\n max-width: 200px;\n position: relative;\n }\n\n .action .remove-button {\n position: absolute;\n top: 5px;\n right: 5px;\n width: 16px;\n height: 16px;\n border-radius: 50%;\n background: var(--color-error, #dc3545);\n color: white;\n border: none;\n cursor: pointer;\n display: none;\n align-items: center;\n justify-content: center;\n font-size: 10px;\n line-height: 1;\n z-index: 10;\n }\n\n .action:hover .remove-button {\n display: flex;\n }\n\n .action.removing .title {\n background-color: var(--color-error, #dc3545) !important;\n }\n\n .action.removing .title .name {\n color: white;\n }\n\n .action.sortable {\n display: flex;\n align-items: stretch;\n }\n\n .action .action-content {\n flex-grow: 1;\n display: flex;\n flex-direction: column;\n }\n\n .action .body {\n padding: 1em;\n }\n\n .action .drag-handle {\n opacity: 0;\n transition: all 200ms ease-in-out;\n cursor: move;\n background: rgba(0, 0, 0, 0.02);\n max-width:0px;\n position: absolute;\n }\n\n .action:hover .drag-handle {\n opacity: 0.5;\n padding: 0.25em;\n max-width: 20px;\n }\n\n .action .drag-handle:hover {\n opacity: 1;\n \n }\n\n .action .title,\n .router .title {\n display: flex;\n color: #fff;\n padding: 5px 1px;\n text-align: center;\n font-size: 1em;\n font-weight: normal;\n\n }\n\n .title .name {\n flex-grow: 1;\n }\n\n .quick-replies {\n margin-top: 0.5em;\n }\n\n .quick-reply {\n background-color: #f0f0f0;\n border: 1px solid #e0e0e0;\n border-radius: calc(var(--curvature) * 1.5);\n padding: 0.2em 1em;\n display: inline-block;\n font-size: 0.8em;\n margin: 0.2em;\n }\n\n .categories {\n display: flex;\n flex-direction: row;\n\n }\n\n .category {\n margin:-1px -0.5px;\n border: 1px solid #f3f3f3;\n padding: 0.75em;\n flex-grow:1;\n text-align: center;\n display: flex;\n flex-direction: column;\n }\n\n .action-exits {\n padding-bottom: 0.6em;\n margin-top: -0.8em;\n }\n\n .category .title {\n font-weight: normal;\n font-size: 1em;\n }\n\n .router .body {\n padding: 0.75em;\n }\n\n .result-name {\n font-weight: bold;\n display: inline-block;\n }\n \n .exit-wrapper {\n display: flex;\n justify-content: center;\n align-items: center;\n position: relative;\n margin-bottom: -1.2em;\n padding-top:0.2em;\n }\n\n .exit {\n width: 12px;\n height: 12px;\n border-radius: 50%;\n background-color: tomato;\n position: relative;\n box-shadow: 0 2px 2px rgba(0, 0, 0, .1);\n cursor: pointer;\n pointer-events: none;\n }\n\n .exit.jtk-connected {\n background: var(--color-connectors, #e6e6e6);\n }\n\n .exit.connected {\n background-color: #fff;\n pointer-events: all;\n }\n\n .exit.connected:hover {\n background-color: var(--color-connectors, #e6e6e6);\n }\n \n .exit.removing, .exit.removing:hover {\n background-color: var(--color-error);\n pointer-events: all;\n }\n \n .exit.removing::before {\n content: '✕';\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n font-size: 8px;\n color: white;\n line-height: 1;\n }\n \n /* Connector in removing state */\n :host {\n --color-connector-removing: var(--color-error);\n }\n \n body svg.plumb-connector.removing path {\n stroke: var(--color-connector-removing, tomato) !important;\n stroke-width: 3px;\n }\n \n body .plumb-connector.removing .plumb-arrow {\n fill: var(--color-connector-removing, tomato) !important;\n stroke: var(--color-connector-removing, transparent) !important;\n }\n\n .category:first-child {\n border-bottom-left-radius: var(--curvature);\n }\n\n .category:last-child {\n border-bottom-right-radius: var(--curvature);\n }\n\n .router .title {\n border-top-left-radius: var(--curvature);\n border-top-right-radius: var(--curvature);\n }\n\n .action{\n overflow: hidden;\n }\n\n .action:first-child .title {\n border-top-left-radius: var(--curvature);\n border-top-right-radius: var(--curvature);\n }\n }`;\n }\n\n constructor() {\n super();\n this.handleActionOrderChanged = this.handleActionOrderChanged.bind(this);\n }\n\n protected updated(\n changes: PropertyValueMap<any> | Map<PropertyKey, unknown>\n ): void {\n super.updated(changes);\n if (changes.has('node')) {\n // make our initial connections\n if (changes.get('node') === undefined) {\n for (const exit of this.node.exits) {\n if (!exit.destination_uuid) {\n this.plumber.makeSource(exit.uuid);\n } else {\n this.plumber.connectIds(\n this.node.uuid,\n exit.uuid,\n exit.destination_uuid\n );\n }\n }\n }\n\n const ele = this.parentElement;\n const rect = ele.getBoundingClientRect();\n\n getStore()\n ?.getState()\n .expandCanvas(\n this.ui.position.left + rect.width,\n this.ui.position.top + rect.height\n );\n }\n }\n\n disconnectedCallback() {\n // Remove the event listener when the component is removed\n super.disconnectedCallback();\n\n // Clear any pending exit removal timeouts\n this.exitRemovalTimeouts.forEach((timeoutId) => {\n clearTimeout(timeoutId);\n });\n this.exitRemovalTimeouts.clear();\n\n // Clear any pending action removal timeouts\n this.actionRemovalTimeouts.forEach((timeoutId) => {\n clearTimeout(timeoutId);\n });\n this.actionRemovalTimeouts.clear();\n\n // Clear the removing state\n this.exitRemovingState.clear();\n this.actionRemovingState.clear();\n }\n\n private handleExitClick(event: MouseEvent, exit: Exit) {\n event.preventDefault();\n event.stopPropagation();\n\n const exitId = exit.uuid;\n\n // If exit is not connected, do nothing\n if (!exit.destination_uuid) return;\n\n // If the exit is already in removing state, perform the disconnect\n if (this.exitRemovingState.has(exitId)) {\n this.disconnectExit(exit);\n return;\n }\n\n // Start removal UI state\n this.exitRemovingState.add(exitId);\n this.requestUpdate();\n\n // Set the connection to removing state\n this.plumber.setConnectionRemovingState(exitId, true);\n\n // Clear any existing timeout for this exit\n if (this.exitRemovalTimeouts.has(exitId)) {\n clearTimeout(this.exitRemovalTimeouts.get(exitId));\n }\n\n // Set timeout to reset UI if user doesn't click\n const timeoutId = window.setTimeout(() => {\n this.exitRemovingState.delete(exitId);\n this.exitRemovalTimeouts.delete(exitId);\n\n // Reset the connection to normal state\n this.plumber.setConnectionRemovingState(exitId, false);\n\n this.requestUpdate();\n }, 1500);\n\n this.exitRemovalTimeouts.set(exitId, timeoutId);\n }\n\n private disconnectExit(exit: Exit) {\n const exitId = exit.uuid;\n\n // Clear the UI state\n this.exitRemovingState.delete(exitId);\n\n // Reset the connection to normal state (this will be redundant as we're about to remove it,\n // but it's safer to do this in case there's any timing issue)\n this.plumber.setConnectionRemovingState(exitId, false);\n\n // Clear any timeout\n if (this.exitRemovalTimeouts.has(exitId)) {\n clearTimeout(this.exitRemovalTimeouts.get(exitId));\n this.exitRemovalTimeouts.delete(exitId);\n }\n\n // Remove the JSPlumb connection\n this.plumber.removeExitConnection(exitId);\n\n // Update the flow definition\n const updatedExit = { ...exit, destination_uuid: null };\n const updatedExits = this.node.exits.map((e) =>\n e.uuid === exitId ? updatedExit : e\n );\n\n // Update the node\n const updatedNode = { ...this.node, exits: updatedExits };\n getStore()?.getState().updateNode(this.node.uuid, updatedNode);\n\n // Request update to reflect changes\n this.requestUpdate();\n }\n\n private handleActionRemoveClick(\n event: MouseEvent,\n action: Action,\n index: number\n ) {\n event.preventDefault();\n event.stopPropagation();\n\n const actionId = action.uuid;\n\n // If the action is already in removing state, perform the removal\n if (this.actionRemovingState.has(actionId)) {\n this.removeAction(action, index);\n return;\n }\n\n // Start removal UI state\n this.actionRemovingState.add(actionId);\n this.requestUpdate();\n\n // Clear any existing timeout for this action\n if (this.actionRemovalTimeouts.has(actionId)) {\n clearTimeout(this.actionRemovalTimeouts.get(actionId));\n }\n\n // Set timeout to reset UI if user doesn't click\n const timeoutId = window.setTimeout(() => {\n this.actionRemovingState.delete(actionId);\n this.actionRemovalTimeouts.delete(actionId);\n this.requestUpdate();\n }, 1000); // 1 second as per requirements\n\n this.actionRemovalTimeouts.set(actionId, timeoutId);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n private removeAction(action: Action, _index: number) {\n const actionId = action.uuid;\n\n // Clear the UI state\n this.actionRemovingState.delete(actionId);\n\n // Clear any timeout\n if (this.actionRemovalTimeouts.has(actionId)) {\n clearTimeout(this.actionRemovalTimeouts.get(actionId));\n this.actionRemovalTimeouts.delete(actionId);\n }\n\n // Remove the action from the node\n const updatedActions = this.node.actions.filter((a) => a.uuid !== actionId);\n\n // If no actions remain, remove the entire node\n if (updatedActions.length === 0) {\n this.fireCustomEvent(CustomEventType.NodeDeleted, {\n uuid: this.node.uuid\n });\n } else {\n // Update the node with remaining actions\n const updatedNode = { ...this.node, actions: updatedActions };\n getStore()?.getState().updateNode(this.node.uuid, updatedNode);\n\n // Request update to reflect changes\n this.requestUpdate();\n }\n }\n\n private handleActionOrderChanged(event: CustomEvent) {\n const [fromIdx, toIdx] = event.detail.swap;\n\n // swap our actions\n const newActions = [...this.node.actions];\n const movedAction = newActions.splice(fromIdx, 1)[0];\n newActions.splice(toIdx, 0, movedAction);\n\n // udate our internal reprensentation, this isn't strictly necessary\n // since the editor will update us from it's definition subscription\n // but it makes testing a lot easier\n this.node = { ...this.node, actions: newActions };\n\n getStore()\n ?.getState()\n .updateNode(this.node.uuid, { ...this.node, actions: newActions });\n }\n\n private renderTitle(config: UIConfig, isRemoving: boolean = false) {\n return html`<div class=\"title\" style=\"background:${config.color}\">\n ${this.node?.actions?.length > 1\n ? html`<temba-icon class=\"drag-handle\" name=\"sort\"></temba-icon>`\n : null}\n\n <div class=\"name\">${isRemoving ? 'Remove?' : config.name}</div>\n </div>`;\n }\n\n private renderAction(node: Node, action: Action, index: number) {\n const config = EDITOR_CONFIG[action.type];\n const isRemoving = this.actionRemovingState.has(action.uuid);\n\n if (config) {\n return html`<div\n class=\"action sortable ${action.type} ${isRemoving ? 'removing' : ''}\"\n id=\"action-${index}\"\n >\n <button\n class=\"remove-button\"\n @click=${(e: MouseEvent) =>\n this.handleActionRemoveClick(e, action, index)}\n title=\"Remove action\"\n >\n ✕\n </button>\n <div class=\"action-content\">\n ${this.renderTitle(config, isRemoving)}\n <div class=\"body\">\n ${config.render\n ? config.render(node, action)\n : html`<pre>${action.type}</pre>`}\n </div>\n </div>\n </div>`;\n }\n return html`<div\n class=\"action sortable ${isRemoving ? 'removing' : ''}\"\n id=\"action-${index}\"\n >\n <button\n class=\"remove-button\"\n @click=${(e: MouseEvent) =>\n this.handleActionRemoveClick(e, action, index)}\n title=\"Remove action\"\n >\n ✕\n </button>\n ${action.type}\n </div>`;\n }\n\n private renderRouter(router: Router, ui: NodeUI) {\n const config = EDITOR_CONFIG[ui.type];\n if (config) {\n return html`<div class=\"router\">\n ${this.renderTitle(config, false)}\n ${router.result_name\n ? html`<div class=\"body\">\n Save as\n <div class=\"result-name\">${router.result_name}</div>\n </div>`\n : null}\n </div>`;\n }\n }\n\n private renderCategories(node: Node) {\n if (!node.router || !node.router.categories) {\n return null;\n }\n const categories = node.router.categories.map((category) => {\n const exit = node.exits.find(\n (exit: Exit) => exit.uuid == category.exit_uuid\n );\n\n return html`<div class=\"category\">\n <div class=\"title\">${category.name}</div>\n ${this.renderExit(exit)}\n </div>`;\n });\n\n return html`<div class=\"categories\">${categories}</div>`;\n }\n\n private renderExit(exit: Exit): TemplateResult {\n return html`<div class=\"exit-wrapper\">\n <div\n id=\"${exit.uuid}\"\n class=${getClasses({\n exit: true,\n connected: !!exit.destination_uuid,\n removing: this.exitRemovingState.has(exit.uuid)\n })}\n @click=${(e: MouseEvent) => this.handleExitClick(e, exit)}\n ></div>\n </div>`;\n }\n\n public render() {\n if (!this.node || !this.ui) {\n return html`<div class=\"node\">Loading...</div>`;\n }\n\n return html`\n <div\n id=\"${this.node.uuid}\"\n class=\"node\"\n style=\"left:${this.ui.position.left}px;top:${this.ui.position.top}px\"\n >\n ${this.node.actions.length > 0\n ? html`<temba-sortable-list\n dragHandle=\"drag-handle\"\n @temba-order-changed=\"${this.handleActionOrderChanged}\"\n >\n ${this.node.actions.map((actionSpec, index) => {\n return this.renderAction(this.node, actionSpec, index);\n })}\n </temba-sortable-list>`\n : ''}\n ${this.node.router\n ? html` ${this.renderRouter(this.node.router, this.ui)}\n ${this.renderCategories(this.node)}`\n : html`<div class=\"action-exits\">\n ${this.node.exits.map((exit) => {\n return this.renderExit(exit);\n })}\n </div>`}\n </div>\n `;\n }\n}\n"]}
@@ -1,19 +1,38 @@
1
- import { DotEndpoint, FlowchartConnector, newInstance, ready, RectangleEndpoint } from '@jsplumb/browser-ui';
1
+ import { DotEndpoint, FlowchartConnector, newInstance, ready, RectangleEndpoint, EVENT_CONNECTION_DRAG, EVENT_CONNECTION_ABORT, INTERCEPT_BEFORE_DROP, EVENT_CONNECTION, EVENT_REVERT, INTERCEPT_BEFORE_DETACH, EVENT_CONNECTION_DETACHED } from '@jsplumb/browser-ui';
2
+ const CONNECTOR_DEFAULTS = {
3
+ type: FlowchartConnector.type,
4
+ options: {
5
+ stub: [20, 10],
6
+ midpoint: 0.5,
7
+ alwaysRespectStubs: true,
8
+ cornerRadius: 5,
9
+ cssClass: 'plumb-connector'
10
+ }
11
+ };
12
+ const OVERLAYS_DEFAULTS = [
13
+ {
14
+ type: 'PlainArrow',
15
+ options: {
16
+ width: 13,
17
+ length: 13,
18
+ location: 0.999,
19
+ cssClass: 'plumb-arrow'
20
+ }
21
+ }
22
+ ];
2
23
  export const SOURCE_DEFAULTS = {
3
24
  endpoint: {
4
25
  type: DotEndpoint.type,
5
26
  options: {
6
- radius: 6,
7
- connectedClass: 'plumb-connected',
27
+ radius: 12,
8
28
  cssClass: 'plumb-source',
9
29
  hoverClass: 'plumb-source-hover'
10
30
  }
11
31
  },
12
32
  anchors: ['Bottom', 'Continuous'],
13
33
  maxConnections: 1,
14
- dragAllowedWhenFull: false,
15
- deleteEndpointsOnEmpty: true,
16
- isSource: true
34
+ source: true,
35
+ dragAllowedWhenFull: false
17
36
  };
18
37
  export const TARGET_DEFAULTS = {
19
38
  endpoint: {
@@ -32,21 +51,74 @@ export const TARGET_DEFAULTS = {
32
51
  cssClass: 'continuos plumb-target-anchor'
33
52
  }
34
53
  },
35
- dragAllowedWhenFull: false,
36
- deleteEndpointsOnEmpty: true,
37
- isTarget: true
54
+ deleteOnEmpty: true,
55
+ maxConnections: 1,
56
+ target: true
38
57
  };
39
58
  export class Plumber {
40
59
  constructor(canvas) {
41
60
  this.jsPlumb = null;
42
61
  this.pendingConnections = [];
62
+ this.connectionListeners = new Map();
63
+ this.connectionDragging = false;
43
64
  this.connectionWait = null;
44
65
  ready(() => {
45
66
  this.jsPlumb = newInstance({
46
- container: canvas
67
+ container: canvas,
68
+ connectionsDetachable: true,
69
+ endpointStyle: {
70
+ fill: 'green'
71
+ },
72
+ connector: CONNECTOR_DEFAULTS,
73
+ connectionOverlays: OVERLAYS_DEFAULTS
74
+ });
75
+ // Bind to connection events
76
+ this.jsPlumb.bind(EVENT_CONNECTION, (info) => {
77
+ this.connectionDragging = false;
78
+ this.notifyListeners(EVENT_CONNECTION, info);
79
+ });
80
+ // Bind to connection drag events
81
+ this.jsPlumb.bind(EVENT_CONNECTION_DRAG, (info) => {
82
+ this.connectionDragging = true;
83
+ this.notifyListeners(EVENT_CONNECTION_DRAG, info);
84
+ });
85
+ this.jsPlumb.bind(EVENT_CONNECTION_ABORT, (info) => {
86
+ this.connectionDragging = false;
87
+ this.notifyListeners(EVENT_CONNECTION_ABORT, info);
47
88
  });
89
+ this.jsPlumb.bind(EVENT_CONNECTION_DETACHED, (info) => {
90
+ this.connectionDragging = false;
91
+ this.notifyListeners(EVENT_CONNECTION_DETACHED, info);
92
+ });
93
+ this.jsPlumb.bind(EVENT_REVERT, (info) => {
94
+ this.notifyListeners(EVENT_REVERT, info);
95
+ });
96
+ this.jsPlumb.bind(INTERCEPT_BEFORE_DROP, () => {
97
+ // we always deny automatic connections
98
+ return false;
99
+ });
100
+ this.jsPlumb.bind(INTERCEPT_BEFORE_DETACH, () => { });
48
101
  });
49
102
  }
103
+ notifyListeners(eventName, info) {
104
+ const listeners = this.connectionListeners.get(eventName) || [];
105
+ listeners.forEach((listener) => listener(info));
106
+ }
107
+ on(eventName, callback) {
108
+ if (!this.connectionListeners.has(eventName)) {
109
+ this.connectionListeners.set(eventName, []);
110
+ }
111
+ this.connectionListeners.get(eventName).push(callback);
112
+ }
113
+ off(eventName, callback) {
114
+ if (!this.connectionListeners.has(eventName))
115
+ return;
116
+ const listeners = this.connectionListeners.get(eventName);
117
+ const index = listeners.indexOf(callback);
118
+ if (index !== -1) {
119
+ listeners.splice(index, 1);
120
+ }
121
+ }
50
122
  makeTarget(uuid) {
51
123
  const element = document.getElementById(uuid);
52
124
  this.jsPlumb.addEndpoint(element, TARGET_DEFAULTS);
@@ -66,9 +138,11 @@ export class Plumber {
66
138
  this.connectionWait = setTimeout(() => {
67
139
  this.jsPlumb.batch(() => {
68
140
  this.pendingConnections.forEach((connection) => {
69
- const { fromId, toId } = connection;
141
+ const { scope, fromId, toId } = connection;
70
142
  const fromElement = document.getElementById(fromId);
71
143
  const toElement = document.getElementById(toId);
144
+ // delete any existing endpoints
145
+ this.jsPlumb.selectEndpoints({ source: fromId }).deleteAll();
72
146
  const source = this.jsPlumb.addEndpoint(fromElement, {
73
147
  ...SOURCE_DEFAULTS,
74
148
  endpoint: {
@@ -84,35 +158,20 @@ export class Plumber {
84
158
  source,
85
159
  target,
86
160
  connector: {
87
- type: FlowchartConnector.type,
88
- options: {
89
- stub: 12,
90
- midpoint: 0.75,
91
- alwaysRespectStubs: false,
92
- gap: [0, 5],
93
- cornerRadius: 3,
94
- cssClass: 'plumb-connector'
95
- }
161
+ ...CONNECTOR_DEFAULTS,
162
+ options: { ...CONNECTOR_DEFAULTS.options, gap: [0, 5] }
96
163
  },
97
- overlays: [
98
- {
99
- type: 'PlainArrow',
100
- options: {
101
- width: 13,
102
- length: 13,
103
- location: 0.999,
104
- cssClass: 'plumb-arrow'
105
- }
106
- }
107
- ]
164
+ data: {
165
+ nodeId: scope
166
+ }
108
167
  });
109
168
  });
110
169
  this.pendingConnections = [];
111
170
  });
112
171
  }, 50);
113
172
  }
114
- connectIds(fromId, toId) {
115
- this.pendingConnections.push({ fromId, toId });
173
+ connectIds(scope, fromId, toId) {
174
+ this.pendingConnections.push({ scope, fromId, toId });
116
175
  this.processPendingConnections();
117
176
  }
118
177
  repaintEverything() {
@@ -120,57 +179,78 @@ export class Plumber {
120
179
  this.jsPlumb.repaintEverything();
121
180
  }
122
181
  }
123
- elevateNodeConnections(nodeId) {
182
+ revalidate(ids) {
124
183
  if (!this.jsPlumb)
125
184
  return;
126
- // Get all connections
127
- const connections = this.jsPlumb.getConnections();
128
- // Get the node element to find its exit elements
129
- const nodeElement = document.getElementById(nodeId);
130
- const exitElements = nodeElement
131
- ? nodeElement.querySelectorAll('.exit')
132
- : [];
133
- const exitIds = Array.from(exitElements).map((exit) => exit.id);
134
- connections.forEach((connection) => {
135
- const sourceId = connection.source.id;
136
- const targetId = connection.target.id;
137
- // Check if this connection involves the dragged node:
138
- // - Incoming: target is the node itself
139
- // - Outgoing: source is one of the node's exits
140
- if (targetId === nodeId || exitIds.includes(sourceId)) {
141
- // Add elevated class to the connector element
142
- const connectorElement = connection.connector.canvas;
143
- if (connectorElement) {
144
- connectorElement.classList.add('elevated');
185
+ this.jsPlumb.batch(() => {
186
+ ids.forEach((id) => {
187
+ const element = document.getElementById(id);
188
+ if (element) {
189
+ this.jsPlumb.revalidate(element);
145
190
  }
146
- }
191
+ });
192
+ });
193
+ }
194
+ removeNodeConnections(nodeId) {
195
+ var _a;
196
+ if (!this.jsPlumb)
197
+ return;
198
+ const inbound = this.jsPlumb.select({ target: nodeId });
199
+ // keep track of our source ids that are connected, we'll need new endpoints
200
+ const sourceIds = inbound.map((connection) => connection.sourceId);
201
+ const exitIds = Array.from(((_a = document.getElementById(nodeId)) === null || _a === void 0 ? void 0 : _a.querySelectorAll('.exit')) || []).map((exit) => {
202
+ return exit.id;
203
+ }) || [];
204
+ inbound.deleteAll();
205
+ this.jsPlumb.select({ source: exitIds }).deleteAll();
206
+ this.jsPlumb.selectEndpoints({ source: exitIds }).deleteAll();
207
+ // Recreate source endpoints for each source
208
+ sourceIds.forEach((exitId) => {
209
+ this.makeSource(exitId);
147
210
  });
148
211
  }
149
- restoreNodeConnections(nodeId) {
212
+ removeExitConnection(exitId) {
150
213
  if (!this.jsPlumb)
151
214
  return;
152
- // Get all connections
153
- const connections = this.jsPlumb.getConnections();
154
- // Get the node element to find its exit elements
155
- const nodeElement = document.getElementById(nodeId);
156
- const exitElements = nodeElement
157
- ? nodeElement.querySelectorAll('.exit')
158
- : [];
159
- const exitIds = Array.from(exitElements).map((exit) => exit.id);
215
+ const exitElement = document.getElementById(exitId);
216
+ if (!exitElement)
217
+ return;
218
+ // Get all connections from this exit
219
+ const connections = this.jsPlumb.getConnections({ source: exitElement });
220
+ // Remove the connections
160
221
  connections.forEach((connection) => {
161
- const sourceId = connection.source.id;
162
- const targetId = connection.target.id;
163
- // Check if this connection involves the node:
164
- // - Incoming: target is the node itself
165
- // - Outgoing: source is one of the node's exits
166
- if (targetId === nodeId || exitIds.includes(sourceId)) {
167
- // Remove elevated class from the connector element
168
- const connectorElement = connection.connector.canvas;
169
- if (connectorElement) {
170
- connectorElement.classList.remove('elevated');
171
- }
222
+ this.jsPlumb.deleteConnection(connection);
223
+ });
224
+ // Re-create the source endpoint (now without connection)
225
+ this.jsPlumb.removeAllEndpoints(exitElement);
226
+ this.makeSource(exitId);
227
+ return connections.length > 0;
228
+ }
229
+ /**
230
+ * Set the removing state for an exit's connection
231
+ * @param exitId The ID of the exit whose connections should be marked as removing
232
+ * @returns true if connections were found and updated, false otherwise
233
+ */
234
+ setConnectionRemovingState(exitId, isRemoving) {
235
+ if (!this.jsPlumb)
236
+ return false;
237
+ const exitElement = document.getElementById(exitId);
238
+ if (!exitElement)
239
+ return false;
240
+ // Get all connections from this exit
241
+ const connections = this.jsPlumb.getConnections({ source: exitElement });
242
+ if (connections.length === 0)
243
+ return false;
244
+ // Update the connections' CSS classes
245
+ connections.forEach((connection) => {
246
+ if (isRemoving) {
247
+ connection.addClass('removing');
248
+ }
249
+ else {
250
+ connection.removeClass('removing');
172
251
  }
173
252
  });
253
+ return true;
174
254
  }
175
255
  }
176
256
  //# sourceMappingURL=Plumber.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Plumber.js","sourceRoot":"","sources":["../../../src/flow/Plumber.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n DotEndpoint,\n FlowchartConnector,\n newInstance,\n ready,\n RectangleEndpoint\n} from '@jsplumb/browser-ui';\n\nexport const SOURCE_DEFAULTS = {\n endpoint: {\n type: DotEndpoint.type,\n options: {\n radius: 6,\n connectedClass: 'plumb-connected',\n cssClass: 'plumb-source',\n hoverClass: 'plumb-source-hover'\n }\n },\n anchors: ['Bottom', 'Continuous'],\n maxConnections: 1,\n dragAllowedWhenFull: false,\n deleteEndpointsOnEmpty: true,\n isSource: true\n};\n\nexport const TARGET_DEFAULTS = {\n endpoint: {\n type: RectangleEndpoint.type,\n options: {\n width: 23,\n height: 23,\n cssClass: 'plumb-target',\n hoverClass: 'plumb-target-hover'\n }\n },\n anchor: {\n type: 'Continuous',\n options: {\n faces: ['top', 'left', 'right'],\n cssClass: 'continuos plumb-target-anchor'\n }\n },\n dragAllowedWhenFull: false,\n deleteEndpointsOnEmpty: true,\n isTarget: true\n};\n\nexport class Plumber {\n private jsPlumb = null;\n private pendingConnections = [];\n\n constructor(canvas: HTMLElement) {\n ready(() => {\n this.jsPlumb = newInstance({\n container: canvas\n });\n });\n }\n\n public makeTarget(uuid: string) {\n const element = document.getElementById(uuid);\n this.jsPlumb.addEndpoint(element, TARGET_DEFAULTS);\n }\n\n public makeSource(uuid: string) {\n const element = document.getElementById(uuid);\n this.jsPlumb.addEndpoint(element, SOURCE_DEFAULTS);\n }\n\n private connectionWait = null;\n\n // we'll process our pending connections, but we want to debounce this\n public processPendingConnections() {\n // if we have a pending connection wait, clear it\n if (this.connectionWait) {\n clearTimeout(this.connectionWait);\n this.connectionWait = null;\n }\n\n // debounce the connection processing\n this.connectionWait = setTimeout(() => {\n this.jsPlumb.batch(() => {\n this.pendingConnections.forEach((connection) => {\n const { fromId, toId } = connection;\n const fromElement = document.getElementById(fromId);\n const toElement = document.getElementById(toId);\n\n const source = this.jsPlumb.addEndpoint(fromElement, {\n ...SOURCE_DEFAULTS,\n endpoint: {\n ...SOURCE_DEFAULTS.endpoint,\n options: {\n ...SOURCE_DEFAULTS.endpoint.options,\n cssClass: 'plumb-source connected'\n }\n }\n });\n const target = this.jsPlumb.addEndpoint(toElement, TARGET_DEFAULTS);\n this.jsPlumb.connect({\n source,\n target,\n connector: {\n type: FlowchartConnector.type,\n options: {\n stub: 12,\n midpoint: 0.75,\n alwaysRespectStubs: false,\n gap: [0, 5],\n cornerRadius: 3,\n cssClass: 'plumb-connector'\n }\n },\n overlays: [\n {\n type: 'PlainArrow',\n options: {\n width: 13,\n length: 13,\n location: 0.999,\n cssClass: 'plumb-arrow'\n }\n }\n ]\n });\n });\n this.pendingConnections = [];\n });\n }, 50);\n }\n\n public connectIds(fromId: string, toId: string) {\n this.pendingConnections.push({ fromId, toId });\n this.processPendingConnections();\n }\n\n public repaintEverything() {\n if (this.jsPlumb) {\n this.jsPlumb.repaintEverything();\n }\n }\n public elevateNodeConnections(nodeId: string) {\n if (!this.jsPlumb) return;\n\n // Get all connections\n const connections = this.jsPlumb.getConnections();\n\n // Get the node element to find its exit elements\n const nodeElement = document.getElementById(nodeId);\n const exitElements = nodeElement\n ? nodeElement.querySelectorAll('.exit')\n : [];\n const exitIds = Array.from(exitElements).map((exit) => exit.id);\n\n connections.forEach((connection) => {\n const sourceId = connection.source.id;\n const targetId = connection.target.id;\n\n // Check if this connection involves the dragged node:\n // - Incoming: target is the node itself\n // - Outgoing: source is one of the node's exits\n if (targetId === nodeId || exitIds.includes(sourceId)) {\n // Add elevated class to the connector element\n const connectorElement = connection.connector.canvas;\n if (connectorElement) {\n connectorElement.classList.add('elevated');\n }\n }\n });\n }\n\n public restoreNodeConnections(nodeId: string) {\n if (!this.jsPlumb) return;\n\n // Get all connections\n const connections = this.jsPlumb.getConnections();\n\n // Get the node element to find its exit elements\n const nodeElement = document.getElementById(nodeId);\n const exitElements = nodeElement\n ? nodeElement.querySelectorAll('.exit')\n : [];\n const exitIds = Array.from(exitElements).map((exit) => exit.id);\n\n connections.forEach((connection) => {\n const sourceId = connection.source.id;\n const targetId = connection.target.id;\n\n // Check if this connection involves the node:\n // - Incoming: target is the node itself\n // - Outgoing: source is one of the node's exits\n if (targetId === nodeId || exitIds.includes(sourceId)) {\n // Remove elevated class from the connector element\n const connectorElement = connection.connector.canvas;\n if (connectorElement) {\n connectorElement.classList.remove('elevated');\n }\n }\n });\n }\n}\n"]}
1
+ {"version":3,"file":"Plumber.js","sourceRoot":"","sources":["../../../src/flow/Plumber.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n DotEndpoint,\n FlowchartConnector,\n newInstance,\n ready,\n RectangleEndpoint,\n EVENT_CONNECTION_DRAG,\n EVENT_CONNECTION_ABORT,\n INTERCEPT_BEFORE_DROP,\n EVENT_CONNECTION,\n EVENT_REVERT,\n INTERCEPT_BEFORE_DETACH,\n EVENT_CONNECTION_DETACHED\n} from '@jsplumb/browser-ui';\n\nconst CONNECTOR_DEFAULTS = {\n type: FlowchartConnector.type,\n options: {\n stub: [20, 10],\n midpoint: 0.5,\n alwaysRespectStubs: true,\n cornerRadius: 5,\n cssClass: 'plumb-connector'\n }\n};\n\nconst OVERLAYS_DEFAULTS = [\n {\n type: 'PlainArrow',\n options: {\n width: 13,\n length: 13,\n location: 0.999,\n cssClass: 'plumb-arrow'\n }\n }\n];\n\nexport const SOURCE_DEFAULTS = {\n endpoint: {\n type: DotEndpoint.type,\n options: {\n radius: 12,\n cssClass: 'plumb-source',\n hoverClass: 'plumb-source-hover'\n }\n },\n anchors: ['Bottom', 'Continuous'],\n maxConnections: 1,\n source: true,\n dragAllowedWhenFull: false\n};\n\nexport const TARGET_DEFAULTS = {\n endpoint: {\n type: RectangleEndpoint.type,\n options: {\n width: 23,\n height: 23,\n cssClass: 'plumb-target',\n hoverClass: 'plumb-target-hover'\n }\n },\n anchor: {\n type: 'Continuous',\n options: {\n faces: ['top', 'left', 'right'],\n cssClass: 'continuos plumb-target-anchor'\n }\n },\n deleteOnEmpty: true,\n maxConnections: 1,\n target: true\n};\n\nexport class Plumber {\n private jsPlumb = null;\n private pendingConnections = [];\n private connectionListeners = new Map();\n public connectionDragging = false;\n private connectionWait = null;\n\n constructor(canvas: HTMLElement) {\n ready(() => {\n this.jsPlumb = newInstance({\n container: canvas,\n connectionsDetachable: true,\n endpointStyle: {\n fill: 'green'\n },\n connector: CONNECTOR_DEFAULTS,\n connectionOverlays: OVERLAYS_DEFAULTS\n });\n\n // Bind to connection events\n this.jsPlumb.bind(EVENT_CONNECTION, (info) => {\n this.connectionDragging = false;\n this.notifyListeners(EVENT_CONNECTION, info);\n });\n\n // Bind to connection drag events\n this.jsPlumb.bind(EVENT_CONNECTION_DRAG, (info) => {\n this.connectionDragging = true;\n this.notifyListeners(EVENT_CONNECTION_DRAG, info);\n });\n\n this.jsPlumb.bind(EVENT_CONNECTION_ABORT, (info) => {\n this.connectionDragging = false;\n this.notifyListeners(EVENT_CONNECTION_ABORT, info);\n });\n\n this.jsPlumb.bind(EVENT_CONNECTION_DETACHED, (info) => {\n this.connectionDragging = false;\n this.notifyListeners(EVENT_CONNECTION_DETACHED, info);\n });\n\n this.jsPlumb.bind(EVENT_REVERT, (info) => {\n this.notifyListeners(EVENT_REVERT, info);\n });\n\n this.jsPlumb.bind(INTERCEPT_BEFORE_DROP, () => {\n // we always deny automatic connections\n return false;\n });\n this.jsPlumb.bind(INTERCEPT_BEFORE_DETACH, () => {});\n });\n }\n\n private notifyListeners(eventName: string, info: any) {\n const listeners = this.connectionListeners.get(eventName) || [];\n listeners.forEach((listener) => listener(info));\n }\n\n public on(eventName: string, callback: (info: any) => void) {\n if (!this.connectionListeners.has(eventName)) {\n this.connectionListeners.set(eventName, []);\n }\n this.connectionListeners.get(eventName).push(callback);\n }\n\n public off(eventName: string, callback: (info: any) => void) {\n if (!this.connectionListeners.has(eventName)) return;\n const listeners = this.connectionListeners.get(eventName);\n const index = listeners.indexOf(callback);\n if (index !== -1) {\n listeners.splice(index, 1);\n }\n }\n\n public makeTarget(uuid: string) {\n const element = document.getElementById(uuid);\n this.jsPlumb.addEndpoint(element, TARGET_DEFAULTS);\n }\n\n public makeSource(uuid: string) {\n const element = document.getElementById(uuid);\n this.jsPlumb.addEndpoint(element, SOURCE_DEFAULTS);\n }\n\n // we'll process our pending connections, but we want to debounce this\n public processPendingConnections() {\n // if we have a pending connection wait, clear it\n if (this.connectionWait) {\n clearTimeout(this.connectionWait);\n this.connectionWait = null;\n }\n\n // debounce the connection processing\n this.connectionWait = setTimeout(() => {\n this.jsPlumb.batch(() => {\n this.pendingConnections.forEach((connection) => {\n const { scope, fromId, toId } = connection;\n const fromElement = document.getElementById(fromId);\n const toElement = document.getElementById(toId);\n\n // delete any existing endpoints\n this.jsPlumb.selectEndpoints({ source: fromId }).deleteAll();\n\n const source = this.jsPlumb.addEndpoint(fromElement, {\n ...SOURCE_DEFAULTS,\n endpoint: {\n ...SOURCE_DEFAULTS.endpoint,\n options: {\n ...SOURCE_DEFAULTS.endpoint.options,\n cssClass: 'plumb-source connected'\n }\n }\n });\n\n const target = this.jsPlumb.addEndpoint(toElement, TARGET_DEFAULTS);\n this.jsPlumb.connect({\n source,\n target,\n connector: {\n ...CONNECTOR_DEFAULTS,\n options: { ...CONNECTOR_DEFAULTS.options, gap: [0, 5] }\n },\n data: {\n nodeId: scope\n }\n });\n });\n this.pendingConnections = [];\n });\n }, 50);\n }\n\n public connectIds(scope: string, fromId: string, toId: string) {\n this.pendingConnections.push({ scope, fromId, toId });\n this.processPendingConnections();\n }\n\n public repaintEverything() {\n if (this.jsPlumb) {\n this.jsPlumb.repaintEverything();\n }\n }\n\n public revalidate(ids: string[]) {\n if (!this.jsPlumb) return;\n this.jsPlumb.batch(() => {\n ids.forEach((id) => {\n const element = document.getElementById(id);\n if (element) {\n this.jsPlumb.revalidate(element);\n }\n });\n });\n }\n\n public removeNodeConnections(nodeId: string) {\n if (!this.jsPlumb) return;\n\n const inbound = this.jsPlumb.select({ target: nodeId });\n\n // keep track of our source ids that are connected, we'll need new endpoints\n const sourceIds = inbound.map((connection) => connection.sourceId);\n\n const exitIds =\n Array.from(\n document.getElementById(nodeId)?.querySelectorAll('.exit') || []\n ).map((exit) => {\n return exit.id;\n }) || [];\n\n inbound.deleteAll();\n this.jsPlumb.select({ source: exitIds }).deleteAll();\n this.jsPlumb.selectEndpoints({ source: exitIds }).deleteAll();\n\n // Recreate source endpoints for each source\n sourceIds.forEach((exitId) => {\n this.makeSource(exitId);\n });\n }\n\n public removeExitConnection(exitId: string) {\n if (!this.jsPlumb) return;\n\n const exitElement = document.getElementById(exitId);\n if (!exitElement) return;\n\n // Get all connections from this exit\n const connections = this.jsPlumb.getConnections({ source: exitElement });\n\n // Remove the connections\n connections.forEach((connection) => {\n this.jsPlumb.deleteConnection(connection);\n });\n\n // Re-create the source endpoint (now without connection)\n this.jsPlumb.removeAllEndpoints(exitElement);\n this.makeSource(exitId);\n\n return connections.length > 0;\n }\n\n /**\n * Set the removing state for an exit's connection\n * @param exitId The ID of the exit whose connections should be marked as removing\n * @returns true if connections were found and updated, false otherwise\n */\n public setConnectionRemovingState(\n exitId: string,\n isRemoving: boolean\n ): boolean {\n if (!this.jsPlumb) return false;\n\n const exitElement = document.getElementById(exitId);\n if (!exitElement) return false;\n\n // Get all connections from this exit\n const connections = this.jsPlumb.getConnections({ source: exitElement });\n\n if (connections.length === 0) return false;\n\n // Update the connections' CSS classes\n connections.forEach((connection) => {\n if (isRemoving) {\n connection.addClass('removing');\n } else {\n connection.removeClass('removing');\n }\n });\n\n return true;\n }\n}\n"]}