n8n-editor-ui 1.44.0 → 1.44.1

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 (150) hide show
  1. package/.turbo/turbo-build.log +77 -77
  2. package/dist/assets/{AuthView-1FRMwQ3r.js → AuthView-DfyvaM6i.js} +2 -2
  3. package/dist/assets/{AuthView-1FRMwQ3r.js.map → AuthView-DfyvaM6i.js.map} +1 -1
  4. package/dist/assets/{CanvasControls-FCzUEVOQ.js → CanvasControls-DFdnF5qb.js} +2 -2
  5. package/dist/assets/{CanvasControls-FCzUEVOQ.js.map → CanvasControls-DFdnF5qb.js.map} +1 -1
  6. package/dist/assets/{ChangePasswordView-DdWHauKg.js → ChangePasswordView-B4v8DwW9.js} +2 -2
  7. package/dist/assets/{ChangePasswordView-DdWHauKg.js.map → ChangePasswordView-B4v8DwW9.js.map} +1 -1
  8. package/dist/assets/{CollectionParameter-CiMzJaXg.js → CollectionParameter-5V5xJsjs.js} +2 -2
  9. package/dist/assets/CollectionParameter-5V5xJsjs.js.map +1 -0
  10. package/dist/assets/{CredentialsView-Bn6PVi9E.js → CredentialsView-tyjXlz4Z.js} +2 -2
  11. package/dist/assets/{CredentialsView-Bn6PVi9E.js.map → CredentialsView-tyjXlz4Z.js.map} +1 -1
  12. package/dist/assets/{ExecutionsFilter-nFboBzV2.js → ExecutionsFilter-0t_omffh.js} +2 -2
  13. package/dist/assets/{ExecutionsFilter-nFboBzV2.js.map → ExecutionsFilter-0t_omffh.js.map} +1 -1
  14. package/dist/assets/{ExecutionsView-CbkLSsSW.js → ExecutionsView-DzCvkqXG.js} +2 -2
  15. package/dist/assets/{ExecutionsView-CbkLSsSW.js.map → ExecutionsView-DzCvkqXG.js.map} +1 -1
  16. package/dist/assets/{ForgotMyPasswordView-vPMSx22g.js → ForgotMyPasswordView-D_90K80j.js} +2 -2
  17. package/dist/assets/{ForgotMyPasswordView-vPMSx22g.js.map → ForgotMyPasswordView-D_90K80j.js.map} +1 -1
  18. package/dist/assets/{MainHeader-DedFNVir.js → MainHeader-BYoa1H_e.js} +2 -2
  19. package/dist/assets/{MainHeader-DedFNVir.js.map → MainHeader-BYoa1H_e.js.map} +1 -1
  20. package/dist/assets/{MainSidebar-BNq07OnD.js → MainSidebar-BNsdraIv.js} +2 -2
  21. package/dist/assets/{MainSidebar-BNq07OnD.js.map → MainSidebar-BNsdraIv.js.map} +1 -1
  22. package/dist/assets/{NodeCreation-C0AAIhNs.js → NodeCreation-R9yLdNU1.js} +3 -3
  23. package/dist/assets/{NodeCreation-C0AAIhNs.js.map → NodeCreation-R9yLdNU1.js.map} +1 -1
  24. package/dist/assets/{NodeCreator-ESjCn1LZ.js → NodeCreator-CLzfNOJ5.js} +2 -2
  25. package/dist/assets/{NodeCreator-ESjCn1LZ.js.map → NodeCreator-CLzfNOJ5.js.map} +1 -1
  26. package/dist/assets/{NodeList-baCRAzNs.js → NodeList-B4yRfzDq.js} +2 -2
  27. package/dist/assets/{NodeList-baCRAzNs.js.map → NodeList-B4yRfzDq.js.map} +1 -1
  28. package/dist/assets/{NodeView-BucVYztm.js → NodeView-BGtpd_Bb.js} +4 -4
  29. package/dist/assets/{NodeView-BucVYztm.js.map → NodeView-BGtpd_Bb.js.map} +1 -1
  30. package/dist/assets/{NodeView.v2-Oz2vwdfG.js → NodeView.v2-DnTCsiDE.js} +3 -3
  31. package/dist/assets/{NodeView.v2-Oz2vwdfG.js.map → NodeView.v2-DnTCsiDE.js.map} +1 -1
  32. package/dist/assets/{ProjectCardBadge.vue_vue_type_script_setup_true_lang-BRGRmswR.js → ProjectCardBadge.vue_vue_type_script_setup_true_lang-CYFr8_zj.js} +2 -2
  33. package/dist/assets/{ProjectCardBadge.vue_vue_type_script_setup_true_lang-BRGRmswR.js.map → ProjectCardBadge.vue_vue_type_script_setup_true_lang-CYFr8_zj.js.map} +1 -1
  34. package/dist/assets/{ProjectSettings-D3FAGvAm.js → ProjectSettings-kayD4yS7.js} +2 -2
  35. package/dist/assets/{ProjectSettings-D3FAGvAm.js.map → ProjectSettings-kayD4yS7.js.map} +1 -1
  36. package/dist/assets/{ProjectTabs-B_U7Q16t.js → ProjectTabs-1jmisSQb.js} +2 -2
  37. package/dist/assets/{ProjectTabs-B_U7Q16t.js.map → ProjectTabs-1jmisSQb.js.map} +1 -1
  38. package/dist/assets/{PushConnectionTracker-DQVvJ6kh.js → PushConnectionTracker-Dfvjg1ts.js} +2 -2
  39. package/dist/assets/{PushConnectionTracker-DQVvJ6kh.js.map → PushConnectionTracker-Dfvjg1ts.js.map} +1 -1
  40. package/dist/assets/{ResourcesListLayout-CfzMCzp5.js → ResourcesListLayout-BOYOLez8.js} +2 -2
  41. package/dist/assets/{ResourcesListLayout-CfzMCzp5.js.map → ResourcesListLayout-BOYOLez8.js.map} +1 -1
  42. package/dist/assets/{RunDataAi-CwnKkFZ1.js → RunDataAi-CFKU0i2R.js} +2 -2
  43. package/dist/assets/{RunDataAi-CwnKkFZ1.js.map → RunDataAi-CFKU0i2R.js.map} +1 -1
  44. package/dist/assets/{RunDataJson-DTMT_R5P.js → RunDataJson-DHI409Ix.js} +3 -3
  45. package/dist/assets/{RunDataJson-DTMT_R5P.js.map → RunDataJson-DHI409Ix.js.map} +1 -1
  46. package/dist/assets/{RunDataJsonActions-dNlM_YO3.js → RunDataJsonActions-LAsoJBBD.js} +2 -2
  47. package/dist/assets/{RunDataJsonActions-dNlM_YO3.js.map → RunDataJsonActions-LAsoJBBD.js.map} +1 -1
  48. package/dist/assets/{RunDataSchema-D7rSFQ4v.js → RunDataSchema-CgYDgOLN.js} +2 -2
  49. package/dist/assets/{RunDataSchema-D7rSFQ4v.js.map → RunDataSchema-CgYDgOLN.js.map} +1 -1
  50. package/dist/assets/{RunDataSearch-BLxgvPWc.js → RunDataSearch-ZJd98FoH.js} +2 -2
  51. package/dist/assets/{RunDataSearch-BLxgvPWc.js.map → RunDataSearch-ZJd98FoH.js.map} +1 -1
  52. package/dist/assets/{RunDataTable-CTYOMGVf.js → RunDataTable-IMqti3UV.js} +2 -2
  53. package/dist/assets/{RunDataTable-CTYOMGVf.js.map → RunDataTable-IMqti3UV.js.map} +1 -1
  54. package/dist/assets/{SamlOnboarding-B0SKUJ7w.js → SamlOnboarding-6S1cZAZQ.js} +2 -2
  55. package/dist/assets/{SamlOnboarding-B0SKUJ7w.js.map → SamlOnboarding-6S1cZAZQ.js.map} +1 -1
  56. package/dist/assets/{SettingsApiView-04CpGWS3.js → SettingsApiView-DzACRdqO.js} +2 -2
  57. package/dist/assets/{SettingsApiView-04CpGWS3.js.map → SettingsApiView-DzACRdqO.js.map} +1 -1
  58. package/dist/assets/{SettingsCommunityNodesView-CNryAAn3.js → SettingsCommunityNodesView-DI8tm65K.js} +2 -2
  59. package/dist/assets/{SettingsCommunityNodesView-CNryAAn3.js.map → SettingsCommunityNodesView-DI8tm65K.js.map} +1 -1
  60. package/dist/assets/{SettingsExternalSecrets-B39P4p2-.js → SettingsExternalSecrets-DFb1WNlI.js} +2 -2
  61. package/dist/assets/{SettingsExternalSecrets-B39P4p2-.js.map → SettingsExternalSecrets-DFb1WNlI.js.map} +1 -1
  62. package/dist/assets/{SettingsFakeDoorView-BOQAY92v.js → SettingsFakeDoorView-CDAZibIu.js} +2 -2
  63. package/dist/assets/{SettingsFakeDoorView-BOQAY92v.js.map → SettingsFakeDoorView-CDAZibIu.js.map} +1 -1
  64. package/dist/assets/{SettingsLdapView-VTF-EB0a.js → SettingsLdapView-yXjpScE1.js} +2 -2
  65. package/dist/assets/{SettingsLdapView-VTF-EB0a.js.map → SettingsLdapView-yXjpScE1.js.map} +1 -1
  66. package/dist/assets/{SettingsLogStreamingView-JsodKkoJ.js → SettingsLogStreamingView-DQTUJczt.js} +2 -2
  67. package/dist/assets/{SettingsLogStreamingView-JsodKkoJ.js.map → SettingsLogStreamingView-DQTUJczt.js.map} +1 -1
  68. package/dist/assets/{SettingsPersonalView-DxQ-hHrk.js → SettingsPersonalView-CYfSdpu7.js} +2 -2
  69. package/dist/assets/{SettingsPersonalView-DxQ-hHrk.js.map → SettingsPersonalView-CYfSdpu7.js.map} +1 -1
  70. package/dist/assets/{SettingsSourceControl-aqaWVYCl.js → SettingsSourceControl-SrxQOR5H.js} +2 -2
  71. package/dist/assets/{SettingsSourceControl-aqaWVYCl.js.map → SettingsSourceControl-SrxQOR5H.js.map} +1 -1
  72. package/dist/assets/{SettingsSso-Chwn0xrx.js → SettingsSso-DrB162SI.js} +2 -2
  73. package/dist/assets/{SettingsSso-Chwn0xrx.js.map → SettingsSso-DrB162SI.js.map} +1 -1
  74. package/dist/assets/{SettingsUsageAndPlan-CIj5SQKn.js → SettingsUsageAndPlan-vOGNFMVq.js} +2 -2
  75. package/dist/assets/{SettingsUsageAndPlan-CIj5SQKn.js.map → SettingsUsageAndPlan-vOGNFMVq.js.map} +1 -1
  76. package/dist/assets/{SettingsUsersView-CY4kSRaG.js → SettingsUsersView-Tx1-g18F.js} +2 -2
  77. package/dist/assets/{SettingsUsersView-CY4kSRaG.js.map → SettingsUsersView-Tx1-g18F.js.map} +1 -1
  78. package/dist/assets/{SettingsView-jgK3_oOB.js → SettingsView-BOZ2SBsQ.js} +2 -2
  79. package/dist/assets/{SettingsView-jgK3_oOB.js.map → SettingsView-BOZ2SBsQ.js.map} +1 -1
  80. package/dist/assets/{SetupView-O6xv77jO.js → SetupView-DY7tVzgF.js} +2 -2
  81. package/dist/assets/{SetupView-O6xv77jO.js.map → SetupView-DY7tVzgF.js.map} +1 -1
  82. package/dist/assets/{SetupWorkflowCredentialsButton-oGzzXD7H.js → SetupWorkflowCredentialsButton-B9Acgowu.js} +2 -2
  83. package/dist/assets/{SetupWorkflowCredentialsButton-oGzzXD7H.js.map → SetupWorkflowCredentialsButton-B9Acgowu.js.map} +1 -1
  84. package/dist/assets/{SetupWorkflowFromTemplateView-BDUp9JWx.js → SetupWorkflowFromTemplateView-C2E8A8g4.js} +2 -2
  85. package/dist/assets/{SetupWorkflowFromTemplateView-BDUp9JWx.js.map → SetupWorkflowFromTemplateView-C2E8A8g4.js.map} +1 -1
  86. package/dist/assets/{SigninView-BLgTm7p4.js → SigninView-DlT1Bv9l.js} +2 -2
  87. package/dist/assets/{SigninView-BLgTm7p4.js.map → SigninView-DlT1Bv9l.js.map} +1 -1
  88. package/dist/assets/{SignoutView-DFSKFmE2.js → SignoutView-DisgJoQS.js} +2 -2
  89. package/dist/assets/{SignoutView-DFSKFmE2.js.map → SignoutView-DisgJoQS.js.map} +1 -1
  90. package/dist/assets/{SignupView-DSmDdbRA.js → SignupView-CQZSGNCi.js} +2 -2
  91. package/dist/assets/{SignupView-DSmDdbRA.js.map → SignupView-CQZSGNCi.js.map} +1 -1
  92. package/dist/assets/{TemplateDetails-DW6dTHAk.js → TemplateDetails-DZzMxROe.js} +2 -2
  93. package/dist/assets/{TemplateDetails-DW6dTHAk.js.map → TemplateDetails-DZzMxROe.js.map} +1 -1
  94. package/dist/assets/{TemplateList-DHLgDv5f.js → TemplateList-DS0lnbxA.js} +2 -2
  95. package/dist/assets/{TemplateList-DHLgDv5f.js.map → TemplateList-DS0lnbxA.js.map} +1 -1
  96. package/dist/assets/{TemplatesCollectionView-Bix3khnw.js → TemplatesCollectionView-BMck3jn9.js} +2 -2
  97. package/dist/assets/{TemplatesCollectionView-Bix3khnw.js.map → TemplatesCollectionView-BMck3jn9.js.map} +1 -1
  98. package/dist/assets/{TemplatesInfoCarousel-B3u16wII.js → TemplatesInfoCarousel-BYIB7MKZ.js} +2 -2
  99. package/dist/assets/{TemplatesInfoCarousel-B3u16wII.js.map → TemplatesInfoCarousel-BYIB7MKZ.js.map} +1 -1
  100. package/dist/assets/{TemplatesSearchView-CvtrqPXg.js → TemplatesSearchView-aVpZ2G9F.js} +2 -2
  101. package/dist/assets/{TemplatesSearchView-CvtrqPXg.js.map → TemplatesSearchView-aVpZ2G9F.js.map} +1 -1
  102. package/dist/assets/{TemplatesView-DuT3R1EI.js → TemplatesView-CuyRlzAM.js} +2 -2
  103. package/dist/assets/{TemplatesView-DuT3R1EI.js.map → TemplatesView-CuyRlzAM.js.map} +1 -1
  104. package/dist/assets/{TemplatesWorkflowView-C_-zPrQW.js → TemplatesWorkflowView-DAa2SCYE.js} +2 -2
  105. package/dist/assets/{TemplatesWorkflowView-C_-zPrQW.js.map → TemplatesWorkflowView-DAa2SCYE.js.map} +1 -1
  106. package/dist/assets/{VariablesView-CMrDg4Fx.js → VariablesView-57BdyEmO.js} +2 -2
  107. package/dist/assets/{VariablesView-CMrDg4Fx.js.map → VariablesView-57BdyEmO.js.map} +1 -1
  108. package/dist/assets/{WorkerView-BcfdfxOO.js → WorkerView-BLv_CYeM.js} +2 -2
  109. package/dist/assets/{WorkerView-BcfdfxOO.js.map → WorkerView-BLv_CYeM.js.map} +1 -1
  110. package/dist/assets/{WorkflowActivator-BiqeeeBc.js → WorkflowActivator-WjfZFpnK.js} +2 -2
  111. package/dist/assets/{WorkflowActivator-BiqeeeBc.js.map → WorkflowActivator-WjfZFpnK.js.map} +1 -1
  112. package/dist/assets/{WorkflowExecutionsInfoAccordion-CITQoihQ.js → WorkflowExecutionsInfoAccordion-Dv9rbNek.js} +2 -2
  113. package/dist/assets/{WorkflowExecutionsInfoAccordion-CITQoihQ.js.map → WorkflowExecutionsInfoAccordion-Dv9rbNek.js.map} +1 -1
  114. package/dist/assets/{WorkflowExecutionsLandingPage-CnHdLYgR.js → WorkflowExecutionsLandingPage-CsbJPayv.js} +2 -2
  115. package/dist/assets/{WorkflowExecutionsLandingPage-CnHdLYgR.js.map → WorkflowExecutionsLandingPage-CsbJPayv.js.map} +1 -1
  116. package/dist/assets/{WorkflowExecutionsPreview-By0_k6NX.js → WorkflowExecutionsPreview-xxP83pWI.js} +2 -2
  117. package/dist/assets/{WorkflowExecutionsPreview-By0_k6NX.js.map → WorkflowExecutionsPreview-xxP83pWI.js.map} +1 -1
  118. package/dist/assets/WorkflowExecutionsView-c7NCTwks.js +2 -0
  119. package/dist/assets/WorkflowExecutionsView-c7NCTwks.js.map +1 -0
  120. package/dist/assets/{WorkflowHistory-C5ALmvoB.js → WorkflowHistory-DI6sDGlZ.js} +2 -2
  121. package/dist/assets/{WorkflowHistory-C5ALmvoB.js.map → WorkflowHistory-DI6sDGlZ.js.map} +1 -1
  122. package/dist/assets/{WorkflowOnboardingView-hQxsQlm1.js → WorkflowOnboardingView-DVqrTjM4.js} +2 -2
  123. package/dist/assets/{WorkflowOnboardingView-hQxsQlm1.js.map → WorkflowOnboardingView-DVqrTjM4.js.map} +1 -1
  124. package/dist/assets/{WorkflowsView-TF6zcpi6.js → WorkflowsView-DpB66gWH.js} +2 -2
  125. package/dist/assets/{WorkflowsView-TF6zcpi6.js.map → WorkflowsView-DpB66gWH.js.map} +1 -1
  126. package/dist/assets/{cloud-CZc2nauc.js → cloud-bM1gshor.js} +2 -2
  127. package/dist/assets/{cloud-CZc2nauc.js.map → cloud-bM1gshor.js.map} +1 -1
  128. package/dist/assets/{collaboration.store-BkSXOsR4.js → collaboration.store-Ct7EpGqG.js} +2 -2
  129. package/dist/assets/{collaboration.store-BkSXOsR4.js.map → collaboration.store-Ct7EpGqG.js.map} +1 -1
  130. package/dist/assets/{index-CY2ZfL2U.js → index-BQ6Z7VRj.js} +4 -4
  131. package/dist/assets/{index-CY2ZfL2U.js.map → index-BQ6Z7VRj.js.map} +1 -1
  132. package/dist/assets/{nodeCreator.store-CmYeJsEL.js → nodeCreator.store-DAcGJEHy.js} +2 -2
  133. package/dist/assets/{nodeCreator.store-CmYeJsEL.js.map → nodeCreator.store-DAcGJEHy.js.map} +1 -1
  134. package/dist/assets/{templateActions-DvpFnju7.js → templateActions-F64sfZ3n.js} +2 -2
  135. package/dist/assets/{templateActions-DvpFnju7.js.map → templateActions-F64sfZ3n.js.map} +1 -1
  136. package/dist/assets/{useExecutionDebugging-6-sjTvWS.js → useExecutionDebugging-DuMp5DdQ.js} +2 -2
  137. package/dist/assets/{useExecutionDebugging-6-sjTvWS.js.map → useExecutionDebugging-DuMp5DdQ.js.map} +1 -1
  138. package/dist/assets/{useExecutionHelpers-BZpwMJs_.js → useExecutionHelpers-Dt-UJW97.js} +2 -2
  139. package/dist/assets/{useExecutionHelpers-BZpwMJs_.js.map → useExecutionHelpers-Dt-UJW97.js.map} +1 -1
  140. package/dist/assets/{usePushConnection-DI_JaC-X.js → usePushConnection-Kek6sJ0j.js} +2 -2
  141. package/dist/assets/{usePushConnection-DI_JaC-X.js.map → usePushConnection-Kek6sJ0j.js.map} +1 -1
  142. package/dist/assets/{useViewStacks-D-hnVv3F.js → useViewStacks-CSn_e3gA.js} +2 -2
  143. package/dist/assets/{useViewStacks-D-hnVv3F.js.map → useViewStacks-CSn_e3gA.js.map} +1 -1
  144. package/dist/assets/{useWorkflowActivate-lrYalAwm.js → useWorkflowActivate-Bl43vPgP.js} +2 -2
  145. package/dist/assets/{useWorkflowActivate-lrYalAwm.js.map → useWorkflowActivate-Bl43vPgP.js.map} +1 -1
  146. package/dist/index.html +1 -1
  147. package/package.json +1 -1
  148. package/dist/assets/CollectionParameter-CiMzJaXg.js.map +0 -1
  149. package/dist/assets/WorkflowExecutionsView-fiAM1R-f.js +0 -2
  150. package/dist/assets/WorkflowExecutionsView-fiAM1R-f.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"mappings":"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","names":["workflowRunning","nodeDisabledTitle","node","inject","CanvasNodeKey","data","computed","$style","useCssModule","executeNode","toggleDisableNode","deleteNode","openContextMenu","e","type","useNodeConnections","inputs","outputs","mainInputs","unref","input","NodeConnectionType","nonMainInputs","requiredNonMainInputs","mainOutputs","output","nonMainOutputs","label","classes","styles","stylesObject","spacerCount","slots","_useSlots","Render","Component","CanvasNodeConfigurable","CanvasNodeConfiguration","CanvasNodeDefault","h","handle","CanvasNodeHandleKey","props","__props","handleType","isConnectableStart","isConnectableEnd","renderProps","CanvasHandleMainInput","CanvasHandleMainOutput","CanvasHandleNonMain","toRef","provide","nodeTypesStore","useNodeTypesStore","nodeType","inputsWithPosition","mapEndpointWithPosition","Position","outputsWithPosition","position","offsetAxis","endpoint","index","endpoints","id","selected","edgeStyle","path","getBezierPath","emit","__emit","onNodeDragStop","onConnect","args","mapLegacyConnectionsToCanvasConnections","legacyConnections","nodes","mappedConnections","fromNodeName","fromId","_a","fromConnectionType","toPorts","fromIndex","toPort","toId","toConnectionType","toIndex","mapLegacyEndpointsToCanvasConnectionPort","endpointIndex","required","getUniqueNodeName","name","existingNames","i","newName","uuid","useCanvasMapping","workflow","workflowObject","locale","useI18n","renderTypeByNodeType","acc","renderType","nodeInputsById","nodeTypeDescription","workflowObjectNode","NodeHelpers.getNodeInputs","nodeOutputsById","NodeHelpers.getNodeOutputs","elements","connections","connection","getConnectionType","getConnectionLabel","_","pinData","_b","uiStore","useUIStore","runButtonText","NodeCreation","defineAsyncComponent","__vitePreload","n","router","useRouter","route","useRoute","i18n","telemetry","useTelemetry","externalHooks","useExternalHooks","toast","useToast","workflowsStore","useWorkflowsStore","useWorkflowsEEStore","tagsStore","useTagsStore","sourceControlStore","useSourceControlStore","nodeCreatorStore","useNodeCreatorStore","settingsStore","useSettingsStore","credentialsStore","useCredentialsStore","environmentsStore","useEnvironmentsStore","externalSecretsStore","useExternalSecretsStore","rootStore","useRootStore","collaborationStore","useCollaborationStore","runWorkflow","useRunWorkflow","isLoading","ref","readOnlyNotification","workflowId","editableWorkflow","editableWorkflowObject","isDemoRoute","VIEWS","isReadOnlyRoute","isReadOnlyEnvironment","triggerNodes","onMounted","initialize","loadPromises","EnterpriseEditionFeature","error","initializeEditableWorkflow","targetWorkflow","tags","tagIds","tag","onRunWorkflow","onNodePositionUpdate","onCreateNodeConnection","sourceNodeId","sourceNode","sourceNodeName","sourceType","sourceIndex","targetNodeId","targetNode","targetNodeName","targetType","targetIndex","checkIfNodeConnectionIsAllowed","onToggleNodeCreator","source","createNodeActive","nodeCreatorView","REGULAR_NODE_CREATOR_VIEW","TRIGGER_NODE_CREATOR_VIEW","mode","AI_NODE_CREATOR_VIEW","onAddNodes","dragAndDrop","currentPosition","nodePosition","isAutoAdd","openDetail","addNode","lastAddedNode","NodeViewUtils.NODE_SIZE","NodeViewUtils.GRID_SIZE","newNodesOffset","from","to","fromNode","toNode","options","checkIfEditingIsAllowed","newNodeData","createNodeWithDefaultCredentials","nodeVersion","messageContext"],"ignoreList":[],"sources":["../../src/components/canvas/elements/nodes/CanvasNodeToolbar.vue","../../src/composables/useNodeConnections.ts","../../src/components/canvas/elements/nodes/render-types/CanvasNodeDefault.vue","../../src/components/canvas/elements/nodes/render-types/CanvasNodeConfiguration.vue","../../src/components/canvas/elements/nodes/render-types/CanvasNodeConfigurable.vue","../../src/components/canvas/elements/nodes/CanvasNodeRenderer.vue","../../src/components/canvas/elements/handles/render-types/CanvasHandleMainInput.vue","../../src/components/canvas/elements/handles/render-types/CanvasHandleMainOutput.vue","../../src/components/canvas/elements/handles/render-types/CanvasHandleNonMain.vue","../../src/components/canvas/elements/handles/HandleRenderer.vue","../../src/components/canvas/elements/nodes/CanvasNode.vue","../../src/components/canvas/elements/edges/CanvasEdge.vue","../../src/components/canvas/Canvas.vue","../../src/utils/canvasUtilsV2.ts","../../src/composables/useCanvasMapping.ts","../../src/components/canvas/WorkflowCanvas.vue","../../src/components/canvas/elements/buttons/CanvasExecuteWorkflowButton.vue","../../src/views/NodeView.v2.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, inject, useCssModule } from 'vue';\nimport { CanvasNodeKey } from '@/constants';\n\nconst node = inject(CanvasNodeKey);\n\nconst data = computed(() => node?.data.value);\n\nconst $style = useCssModule();\n\n// @TODO\nconst workflowRunning = false;\n\n// @TODO\nconst nodeDisabledTitle = 'Test';\n\n// @TODO\nfunction executeNode() {}\n\n// @TODO\nfunction toggleDisableNode() {}\n\n// @TODO\nfunction deleteNode() {}\n\n// @TODO\nfunction openContextMenu(e: MouseEvent, type: string) {}\n</script>\n\n<template>\n\t<div :class=\"$style.canvasNodeToolbar\">\n\t\t<div :class=\"$style.canvasNodeToolbarItems\">\n\t\t\t<N8nIconButton\n\t\t\t\tv-if=\"data?.renderType !== 'configuration'\"\n\t\t\t\tdata-test-id=\"execute-node-button\"\n\t\t\t\ttype=\"tertiary\"\n\t\t\t\ttext\n\t\t\t\tsize=\"small\"\n\t\t\t\ticon=\"play\"\n\t\t\t\t:disabled=\"workflowRunning\"\n\t\t\t\t:title=\"$locale.baseText('node.testStep')\"\n\t\t\t\t@click=\"executeNode\"\n\t\t\t/>\n\t\t\t<N8nIconButton\n\t\t\t\tdata-test-id=\"disable-node-button\"\n\t\t\t\ttype=\"tertiary\"\n\t\t\t\ttext\n\t\t\t\tsize=\"small\"\n\t\t\t\ticon=\"power-off\"\n\t\t\t\t:title=\"nodeDisabledTitle\"\n\t\t\t\t@click=\"toggleDisableNode\"\n\t\t\t/>\n\t\t\t<N8nIconButton\n\t\t\t\tdata-test-id=\"delete-node-button\"\n\t\t\t\ttype=\"tertiary\"\n\t\t\t\tsize=\"small\"\n\t\t\t\ttext\n\t\t\t\ticon=\"trash\"\n\t\t\t\t:title=\"$locale.baseText('node.delete')\"\n\t\t\t\t@click=\"deleteNode\"\n\t\t\t/>\n\t\t\t<N8nIconButton\n\t\t\t\tdata-test-id=\"overflow-node-button\"\n\t\t\t\ttype=\"tertiary\"\n\t\t\t\tsize=\"small\"\n\t\t\t\ttext\n\t\t\t\ticon=\"ellipsis-h\"\n\t\t\t\t@click=\"(e: MouseEvent) => openContextMenu(e, 'node-button')\"\n\t\t\t/>\n\t\t</div>\n\t</div>\n</template>\n\n<style lang=\"scss\" module>\n.canvasNodeToolbar {\n\tpadding-bottom: var(--spacing-3xs);\n}\n\n.canvasNodeToolbarItems {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n}\n</style>\n","import type { CanvasElementData } from '@/types';\nimport type { MaybeRef } from 'vue';\nimport { computed, unref } from 'vue';\nimport { NodeConnectionType } from 'n8n-workflow';\n\nexport function useNodeConnections({\n\tinputs,\n\toutputs,\n}: {\n\tinputs: MaybeRef<CanvasElementData['inputs']>;\n\toutputs: MaybeRef<CanvasElementData['outputs']>;\n}) {\n\t/**\n\t * Inputs\n\t */\n\n\tconst mainInputs = computed(() =>\n\t\tunref(inputs).filter((input) => input.type === NodeConnectionType.Main),\n\t);\n\n\tconst nonMainInputs = computed(() =>\n\t\tunref(inputs).filter((input) => input.type !== NodeConnectionType.Main),\n\t);\n\n\tconst requiredNonMainInputs = computed(() =>\n\t\tnonMainInputs.value.filter((input) => input.required),\n\t);\n\n\t/**\n\t * Outputs\n\t */\n\n\tconst mainOutputs = computed(() =>\n\t\tunref(outputs).filter((output) => output.type === NodeConnectionType.Main),\n\t);\n\tconst nonMainOutputs = computed(() =>\n\t\tunref(outputs).filter((output) => output.type !== NodeConnectionType.Main),\n\t);\n\n\treturn {\n\t\tmainInputs,\n\t\tnonMainInputs,\n\t\trequiredNonMainInputs,\n\t\tmainOutputs,\n\t\tnonMainOutputs,\n\t};\n}\n","<script lang=\"ts\" setup>\nimport { computed, inject, useCssModule } from 'vue';\nimport { useNodeConnections } from '@/composables/useNodeConnections';\nimport { CanvasNodeKey } from '@/constants';\n\nconst node = inject(CanvasNodeKey);\n\nconst $style = useCssModule();\n\nconst label = computed(() => node?.label.value ?? '');\nconst inputs = computed(() => node?.data.value.inputs ?? []);\nconst outputs = computed(() => node?.data.value.outputs ?? []);\n\nconst { mainOutputs } = useNodeConnections({\n\tinputs,\n\toutputs,\n});\n\nconst classes = computed(() => {\n\treturn {\n\t\t[$style.node]: true,\n\t\t[$style.selected]: node?.selected.value,\n\t};\n});\n\nconst styles = computed(() => {\n\treturn {\n\t\t'--node-main-output-count': mainOutputs.value.length,\n\t};\n});\n</script>\n\n<template>\n\t<div v-if=\"node\" :class=\"classes\" :style=\"styles\" data-test-id=\"canvas-node-default\">\n\t\t<slot />\n\t\t<div v-if=\"label\" :class=\"$style.label\">{{ label }}</div>\n\t</div>\n</template>\n\n<style lang=\"scss\" module>\n.node {\n\theight: calc(100px + max(0, var(--node-main-output-count, 1) - 4) * 50px);\n\twidth: 100px;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tbackground: var(--canvas-node--background, var(--color-canvas-node-background));\n\tborder: 2px solid var(--canvas-node--border-color, var(--color-foreground-xdark));\n\tborder-radius: var(--border-radius-large);\n}\n\n.label {\n\ttop: 100%;\n\tposition: absolute;\n\tfont-size: var(--font-size-m);\n\ttext-align: center;\n\twidth: 100%;\n\tmin-width: 200px;\n\tmargin-top: var(--spacing-2xs);\n}\n\n.selected {\n\tbox-shadow: 0 0 0 4px var(--color-canvas-selected);\n}\n</style>\n","<script lang=\"ts\" setup>\nimport { computed, inject, useCssModule } from 'vue';\nimport { CanvasNodeKey } from '@/constants';\n\nconst node = inject(CanvasNodeKey);\n\nconst $style = useCssModule();\n\nconst label = computed(() => node?.label.value ?? '');\n\nconst classes = computed(() => {\n\treturn {\n\t\t[$style.node]: true,\n\t\t[$style.selected]: node?.selected.value,\n\t};\n});\n</script>\n\n<template>\n\t<div :class=\"classes\" data-test-id=\"canvas-node-configuration\">\n\t\t<slot />\n\t\t<div v-if=\"label\" :class=\"$style.label\">{{ label }}</div>\n\t</div>\n</template>\n\n<style lang=\"scss\" module>\n.node {\n\twidth: 75px;\n\theight: 75px;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tbackground: var(--canvas-node--background, var(--node-type-supplemental-background));\n\tborder: 2px solid var(--canvas-node--border-color, var(--color-foreground-dark));\n\tborder-radius: 50%;\n}\n\n.selected {\n\tbox-shadow: 0 0 0 4px var(--color-canvas-selected);\n}\n\n.label {\n\ttop: 100%;\n\tposition: absolute;\n\tfont-size: var(--font-size-m);\n\ttext-align: center;\n\twidth: 100%;\n\tmin-width: 200px;\n\tmargin-top: var(--spacing-2xs);\n}\n</style>\n","<script lang=\"ts\" setup>\nimport { computed, inject, useCssModule } from 'vue';\nimport { CanvasNodeKey, NODE_INSERT_SPACER_BETWEEN_INPUT_GROUPS } from '@/constants';\nimport { useNodeConnections } from '@/composables/useNodeConnections';\n\nconst node = inject(CanvasNodeKey);\n\nconst $style = useCssModule();\n\nconst label = computed(() => node?.label.value ?? '');\nconst inputs = computed(() => node?.data.value.inputs ?? []);\nconst outputs = computed(() => node?.data.value.outputs ?? []);\n\nconst { nonMainInputs, requiredNonMainInputs } = useNodeConnections({\n\tinputs,\n\toutputs,\n});\n\nconst classes = computed(() => {\n\treturn {\n\t\t[$style.node]: true,\n\t\t[$style.selected]: node?.selected.value,\n\t};\n});\n\nconst styles = computed(() => {\n\tconst stylesObject: {\n\t\t[key: string]: string | number;\n\t} = {};\n\n\tif (requiredNonMainInputs.value.length > 0) {\n\t\tlet spacerCount = 0;\n\t\tif (NODE_INSERT_SPACER_BETWEEN_INPUT_GROUPS) {\n\t\t\tconst requiredNonMainInputsCount = requiredNonMainInputs.value.length;\n\t\t\tconst optionalNonMainInputsCount = nonMainInputs.value.length - requiredNonMainInputsCount;\n\t\t\tspacerCount = requiredNonMainInputsCount > 0 && optionalNonMainInputsCount > 0 ? 1 : 0;\n\t\t}\n\n\t\tstylesObject['--configurable-node-input-count'] = nonMainInputs.value.length + spacerCount;\n\t}\n\n\treturn stylesObject;\n});\n</script>\n\n<template>\n\t<div :class=\"classes\" :style=\"styles\" data-test-id=\"canvas-node-configurable\">\n\t\t<slot />\n\t\t<div :class=\"$style.label\">{{ label }}</div>\n\t</div>\n</template>\n\n<style lang=\"scss\" module>\n.node {\n\t--configurable-node-min-input-count: 4;\n\t--configurable-node-input-width: 65px;\n\n\twidth: calc(\n\t\tmax(var(--configurable-node-input-count, 5), var(--configurable-node-min-input-count)) *\n\t\t\tvar(--configurable-node-input-width)\n\t);\n\theight: 100px;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tbackground: var(--canvas-node--background, var(--color-canvas-node-background));\n\tborder: 2px solid var(--canvas-node--border-color, var(--color-foreground-xdark));\n\tborder-radius: var(--border-radius-large);\n}\n\n.label {\n\ttop: 100%;\n\tfont-size: var(--font-size-m);\n\ttext-align: center;\n\tmargin-left: var(--spacing-s);\n\tmax-width: calc(\n\t\tvar(--node-width) - var(--configurable-node-icon-offset) - var(--configurable-node-icon-size) -\n\t\t\t2 * var(--spacing-s)\n\t);\n}\n\n.selected {\n\tbox-shadow: 0 0 0 4px var(--color-canvas-selected);\n}\n</style>\n","<script lang=\"ts\" setup>\nimport { h, inject } from 'vue';\nimport CanvasNodeDefault from '@/components/canvas/elements/nodes/render-types/CanvasNodeDefault.vue';\nimport CanvasNodeConfiguration from '@/components/canvas/elements/nodes/render-types/CanvasNodeConfiguration.vue';\nimport CanvasNodeConfigurable from '@/components/canvas/elements/nodes/render-types/CanvasNodeConfigurable.vue';\nimport { CanvasNodeKey } from '@/constants';\n\nconst node = inject(CanvasNodeKey);\n\nconst slots = defineSlots<{\n\tdefault?: () => unknown;\n}>();\n\nconst Render = () => {\n\tlet Component;\n\tswitch (node?.data.value.renderType) {\n\t\tcase 'configurable':\n\t\t\tComponent = CanvasNodeConfigurable;\n\t\t\tbreak;\n\n\t\tcase 'configuration':\n\t\t\tComponent = CanvasNodeConfiguration;\n\t\t\tbreak;\n\n\t\tcase 'trigger':\n\t\t\tComponent = CanvasNodeDefault;\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tComponent = CanvasNodeDefault;\n\t}\n\n\treturn h(Component, slots.default);\n};\n</script>\n\n<template>\n\t<Render />\n</template>\n","<script lang=\"ts\" setup>\nimport { computed, inject, useCssModule } from 'vue';\nimport { CanvasNodeHandleKey } from '@/constants';\n\nconst handle = inject(CanvasNodeHandleKey);\n\nconst $style = useCssModule();\n\nconst label = computed(() => handle?.label.value ?? '');\n</script>\n<template>\n\t<div :class=\"['canvas-node-handle-main-input', $style.handle]\">\n\t\t<div :class=\"$style.label\">{{ label }}</div>\n\t</div>\n</template>\n\n<style lang=\"scss\" module>\n.handle {\n\twidth: 8px;\n\theight: 16px;\n\tborder-radius: 0;\n\tbackground: var(--color-foreground-xdark);\n\n\t&:hover {\n\t\tbackground: var(--color-primary);\n\t}\n}\n\n.label {\n\tposition: absolute;\n\ttop: 50%;\n\tright: 12px;\n\ttransform: translate(0, -50%);\n\tfont-size: var(--font-size-2xs);\n\tcolor: var(--color-foreground-xdark);\n\tbackground: var(--color-background-light);\n\tz-index: 1;\n}\n</style>\n","<script lang=\"ts\" setup>\nimport { computed, inject, useCssModule } from 'vue';\nimport { CanvasNodeHandleKey } from '@/constants';\n\nconst handle = inject(CanvasNodeHandleKey);\n\n// const group = svg.node('g');\n// const containerBorder = svg.node('rect', {\n// \trx: 3,\n// \t'stroke-width': 2,\n// \tfillOpacity: 0,\n// \theight: ep.params.dimensions - 2,\n// \twidth: ep.params.dimensions - 2,\n// \ty: 1,\n// \tx: 1,\n// });\n// const plusPath = svg.node('path', {\n// \td: 'm16.40655,10.89837l-3.30491,0l0,-3.30491c0,-0.40555 -0.32889,-0.73443 -0.73443,-0.73443l-0.73443,0c-0.40554,0 -0.73442,0.32888 -0.73442,0.73443l0,3.30491l-3.30491,0c-0.40555,0 -0.73443,0.32888 -0.73443,0.73442l0,0.73443c0,0.40554 0.32888,0.73443 0.73443,0.73443l3.30491,0l0,3.30491c0,0.40554 0.32888,0.73442 0.73442,0.73442l0.73443,0c0.40554,0 0.73443,-0.32888 0.73443,-0.73442l0,-3.30491l3.30491,0c0.40554,0 0.73442,-0.32889 0.73442,-0.73443l0,-0.73443c0,-0.40554 -0.32888,-0.73442 -0.73442,-0.73442z',\n// });\n// if (ep.params.size !== 'medium') {\n// \tep.addClass(ep.params.size);\n// }\n// group.appendChild(containerBorder);\n// group.appendChild(plusPath);\n//\n// ep.setupOverlays();\n// ep.setVisible(false);\n// return group;\n\nconst $style = useCssModule();\n\nconst label = computed(() => handle?.label.value ?? '');\n</script>\n<template>\n\t<div :class=\"['canvas-node-handle-main-output', $style.handle]\">\n\t\t<div :class=\"$style.label\">{{ label }}</div>\n\t\t<div :class=\"$style.circle\" />\n\t\t<!-- @TODO Determine whether handle is connected and find a way to make it work without pointer-events: none -->\n\t\t<!--\t\t<svg :class=\"$style.plus\" viewBox=\"0 0 70 24\">-->\n\t\t<!--\t\t\t<line x1=\"0\" y1=\"12\" x2=\"46\" y2=\"12\" stroke=\"var(&#45;&#45;color-foreground-xdark)\" />-->\n\t\t<!--\t\t\t<rect-->\n\t\t<!--\t\t\t\tx=\"46\"-->\n\t\t<!--\t\t\t\ty=\"2\"-->\n\t\t<!--\t\t\t\twidth=\"20\"-->\n\t\t<!--\t\t\t\theight=\"20\"-->\n\t\t<!--\t\t\t\tstroke=\"var(&#45;&#45;color-foreground-xdark)\"-->\n\t\t<!--\t\t\t\tstroke-width=\"2\"-->\n\t\t<!--\t\t\t\trx=\"4\"-->\n\t\t<!--\t\t\t\tfill=\"#ffffff\"-->\n\t\t<!--\t\t\t/>-->\n\t\t<!--\t\t\t<g transform=\"translate(44, 0)\">-->\n\t\t<!--\t\t\t\t<path-->\n\t\t<!--\t\t\t\t\tfill=\"var(&#45;&#45;color-foreground-xdark)\"-->\n\t\t<!--\t\t\t\t\td=\"m16.40655,10.89837l-3.30491,0l0,-3.30491c0,-0.40555 -0.32889,-0.73443 -0.73443,-0.73443l-0.73443,0c-0.40554,0 -0.73442,0.32888 -0.73442,0.73443l0,3.30491l-3.30491,0c-0.40555,0 -0.73443,0.32888 -0.73443,0.73442l0,0.73443c0,0.40554 0.32888,0.73443 0.73443,0.73443l3.30491,0l0,3.30491c0,0.40554 0.32888,0.73442 0.73442,0.73442l0.73443,0c0.40554,0 0.73443,-0.32888 0.73443,-0.73442l0,-3.30491l3.30491,0c0.40554,0 0.73442,-0.32889 0.73442,-0.73443l0,-0.73443c0,-0.40554 -0.32888,-0.73442 -0.73442,-0.73442z\"-->\n\t\t<!--\t\t\t\t></path>-->\n\t\t<!--\t\t\t</g>-->\n\t\t<!--\t\t</svg>-->\n\t</div>\n</template>\n\n<style lang=\"scss\" module>\n.handle {\n\twidth: 16px;\n\theight: 16px;\n}\n\n.circle {\n\twidth: 16px;\n\theight: 16px;\n\tborder-radius: 100%;\n\tbackground: var(--color-foreground-xdark);\n\n\t&:hover {\n\t\tbackground: var(--color-primary);\n\t}\n}\n\n.plus {\n\tposition: absolute;\n\tleft: 16px;\n\ttop: 50%;\n\ttransform: translate(0, -50%);\n\twidth: 70px;\n\theight: 24px;\n\n\t:global(.vue-flow__handle.connecting) & {\n\t\tdisplay: none;\n\t}\n}\n\n.label {\n\tposition: absolute;\n\ttop: 50%;\n\tleft: 20px;\n\ttransform: translate(0, -50%);\n\tfont-size: var(--font-size-2xs);\n\tcolor: var(--color-foreground-xdark);\n\tbackground: var(--color-background-light);\n\tz-index: 1;\n}\n</style>\n","<script lang=\"ts\" setup>\nimport { computed, inject, useCssModule } from 'vue';\nimport { CanvasNodeHandleKey } from '@/constants';\n\nconst handle = inject(CanvasNodeHandleKey);\n\nconst $style = useCssModule();\n\nconst label = computed(() => handle?.label.value ?? '');\n</script>\n<template>\n\t<div :class=\"['canvas-node-handle-non-main', $style.handle]\">\n\t\t<div :class=\"$style.diamond\" />\n\t\t<div :class=\"$style.label\">{{ label }}</div>\n\t</div>\n</template>\n\n<style lang=\"scss\" module>\n.handle {\n\twidth: 14px;\n\theight: 14px;\n\tborder-radius: 0;\n}\n\n.diamond {\n\twidth: 14px;\n\theight: 14px;\n\ttransform: rotate(45deg);\n\tbackground: hsl(\n\t\tvar(--node-type-supplemental-color-h) var(--node-type-supplemental-color-s)\n\t\t\tvar(--node-type-supplemental-color-l)\n\t);\n\n\t&:hover {\n\t\tbackground: var(--color-primary);\n\t}\n}\n\n.label {\n\tposition: absolute;\n\ttop: 18px;\n\tleft: 50%;\n\ttransform: translate(-50%, 0);\n\tfont-size: var(--font-size-2xs);\n\tcolor: var(--color-foreground-xdark);\n\tbackground: var(--color-background-light);\n\tz-index: 1;\n}\n</style>\n","<script lang=\"ts\" setup>\nimport { computed, h, provide, toRef, useCssModule } from 'vue';\nimport type { CanvasConnectionPort, CanvasElementPortWithPosition } from '@/types';\n\nimport { Handle } from '@vue-flow/core';\nimport { NodeConnectionType } from 'n8n-workflow';\nimport CanvasHandleMainInput from '@/components/canvas/elements/handles/render-types/CanvasHandleMainInput.vue';\nimport CanvasHandleMainOutput from '@/components/canvas/elements/handles/render-types/CanvasHandleMainOutput.vue';\nimport CanvasHandleNonMain from '@/components/canvas/elements/handles/render-types/CanvasHandleNonMain.vue';\nimport { CanvasNodeHandleKey } from '@/constants';\n\nconst props = defineProps<{\n\tmode: 'output' | 'input';\n\tlabel?: string;\n\ttype: CanvasConnectionPort['type'];\n\tindex: CanvasConnectionPort['index'];\n\tposition: CanvasElementPortWithPosition['position'];\n\toffset: CanvasElementPortWithPosition['offset'];\n}>();\n\nconst $style = useCssModule();\n\nconst handleType = computed(() => (props.mode === 'input' ? 'target' : 'source'));\n\nconst isConnectableStart = computed(() => {\n\treturn props.mode === 'output';\n});\n\nconst isConnectableEnd = computed(() => {\n\treturn props.mode === 'input';\n});\n\nconst Render = (renderProps: { label?: string }) => {\n\tlet Component;\n\n\tif (props.type === NodeConnectionType.Main) {\n\t\tif (props.mode === 'input') {\n\t\t\tComponent = CanvasHandleMainInput;\n\t\t} else {\n\t\t\tComponent = CanvasHandleMainOutput;\n\t\t}\n\t} else {\n\t\tComponent = CanvasHandleNonMain;\n\t}\n\n\treturn h(Component, renderProps);\n};\n\n/**\n * Provide\n */\n\nconst label = toRef(props, 'label');\n\nprovide(CanvasNodeHandleKey, {\n\tlabel,\n});\n</script>\n\n<template>\n\t<Handle\n\t\t:id=\"`${mode}s/${type}/${index}`\"\n\t\t:class=\"[$style.handle]\"\n\t\t:type=\"handleType\"\n\t\t:position=\"position\"\n\t\t:style=\"offset\"\n\t\t:connectable-start=\"isConnectableStart\"\n\t\t:connectable-end=\"isConnectableEnd\"\n\t>\n\t\t<Render :label=\"label\" />\n\t</Handle>\n</template>\n\n<style lang=\"scss\" module>\n.handle {\n\twidth: auto;\n\theight: auto;\n\tdisplay: inline-flex;\n\tjustify-content: center;\n\talign-items: center;\n\tborder: 0;\n\tbackground: none;\n\n\t> * {\n\t\tpointer-events: none;\n\t}\n}\n</style>\n","<script lang=\"ts\" setup>\nimport { Position } from '@vue-flow/core';\nimport { computed, provide, toRef } from 'vue';\nimport type {\n\tCanvasElementData,\n\tCanvasConnectionPort,\n\tCanvasElementPortWithPosition,\n} from '@/types';\nimport NodeIcon from '@/components/NodeIcon.vue';\nimport { useNodeTypesStore } from '@/stores/nodeTypes.store';\nimport CanvasNodeToolbar from '@/components/canvas/elements/nodes/CanvasNodeToolbar.vue';\nimport CanvasNodeRenderer from '@/components/canvas/elements/nodes/CanvasNodeRenderer.vue';\nimport HandleRenderer from '@/components/canvas/elements/handles/HandleRenderer.vue';\nimport { useNodeConnections } from '@/composables/useNodeConnections';\nimport { CanvasNodeKey } from '@/constants';\nimport type { NodeProps } from '@vue-flow/core';\n\nconst props = defineProps<NodeProps<CanvasElementData>>();\n\nconst inputs = computed(() => props.data.inputs);\nconst outputs = computed(() => props.data.outputs);\n\nconst nodeTypesStore = useNodeTypesStore();\n\nconst { mainInputs, nonMainInputs, mainOutputs, nonMainOutputs } = useNodeConnections({\n\tinputs,\n\toutputs,\n});\n\nconst nodeType = computed(() => {\n\treturn nodeTypesStore.getNodeType(props.data.type, props.data.typeVersion);\n});\n\n/**\n * Inputs\n */\n\nconst inputsWithPosition = computed(() => {\n\treturn [\n\t\t...mainInputs.value.map(mapEndpointWithPosition(Position.Left, 'top')),\n\t\t...nonMainInputs.value.map(mapEndpointWithPosition(Position.Bottom, 'left')),\n\t];\n});\n\n/**\n * Outputs\n */\n\nconst outputsWithPosition = computed(() => {\n\treturn [\n\t\t...mainOutputs.value.map(mapEndpointWithPosition(Position.Right, 'top')),\n\t\t...nonMainOutputs.value.map(mapEndpointWithPosition(Position.Top, 'left')),\n\t];\n});\n\n/**\n * Endpoints\n */\n\nconst mapEndpointWithPosition =\n\t(position: Position, offsetAxis: 'top' | 'left') =>\n\t(\n\t\tendpoint: CanvasConnectionPort,\n\t\tindex: number,\n\t\tendpoints: CanvasConnectionPort[],\n\t): CanvasElementPortWithPosition => {\n\t\treturn {\n\t\t\t...endpoint,\n\t\t\tposition,\n\t\t\toffset: {\n\t\t\t\t[offsetAxis]: `${(100 / (endpoints.length + 1)) * (index + 1)}%`,\n\t\t\t},\n\t\t};\n\t};\n\n/**\n * Provide\n */\n\nconst id = toRef(props, 'id');\nconst data = toRef(props, 'data');\nconst label = toRef(props, 'label');\nconst selected = toRef(props, 'selected');\n\nprovide(CanvasNodeKey, {\n\tid,\n\tdata,\n\tlabel,\n\tselected,\n\tnodeType,\n});\n</script>\n\n<template>\n\t<div :class=\"$style.canvasNode\" data-test-id=\"canvas-node\">\n\t\t<template v-for=\"source in outputsWithPosition\" :key=\"`${source.type}/${source.index}`\">\n\t\t\t<HandleRenderer\n\t\t\t\tmode=\"output\"\n\t\t\t\tdata-test-id=\"canvas-node-output-handle\"\n\t\t\t\t:type=\"source.type\"\n\t\t\t\t:label=\"source.label\"\n\t\t\t\t:index=\"source.index\"\n\t\t\t\t:position=\"source.position\"\n\t\t\t\t:offset=\"source.offset\"\n\t\t\t/>\n\t\t</template>\n\n\t\t<template v-for=\"target in inputsWithPosition\" :key=\"`${target.type}/${target.index}`\">\n\t\t\t<HandleRenderer\n\t\t\t\tmode=\"input\"\n\t\t\t\tdata-test-id=\"canvas-node-input-handle\"\n\t\t\t\t:type=\"target.type\"\n\t\t\t\t:label=\"target.label\"\n\t\t\t\t:index=\"target.index\"\n\t\t\t\t:position=\"target.position\"\n\t\t\t\t:offset=\"target.offset\"\n\t\t\t/>\n\t\t</template>\n\n\t\t<CanvasNodeToolbar\n\t\t\tv-if=\"nodeType\"\n\t\t\tdata-test-id=\"canvas-node-toolbar\"\n\t\t\t:class=\"$style.canvasNodeToolbar\"\n\t\t/>\n\n\t\t<CanvasNodeRenderer v-if=\"nodeType\">\n\t\t\t<NodeIcon :node-type=\"nodeType\" :size=\"40\" :shrink=\"false\" />\n\t\t\t<!--\t\t\t:color-default=\"iconColorDefault\"-->\n\t\t\t<!--\t\t\t:disabled=\"data.disabled\"-->\n\t\t</CanvasNodeRenderer>\n\t</div>\n</template>\n\n<style lang=\"scss\" module>\n.canvasNode {\n\t&:hover {\n\t\t.canvasNodeToolbar {\n\t\t\tdisplay: flex;\n\t\t\topacity: 1;\n\t\t}\n\t}\n}\n\n.canvasNodeToolbar {\n\tdisplay: none;\n\tposition: absolute;\n\ttop: 0;\n\tleft: 50%;\n\ttransform: translate(-50%, -100%);\n\topacity: 0;\n\ttransition: opacity 0.3s ease;\n}\n</style>\n","<script lang=\"ts\" setup>\nimport type { EdgeProps } from '@vue-flow/core';\nimport { BaseEdge, getBezierPath } from '@vue-flow/core';\nimport { computed } from 'vue';\n\nconst props = defineProps<EdgeProps>();\n\nconst edgeStyle = computed(() => ({\n\tstrokeWidth: 2,\n\t...props.style,\n}));\n\nconst path = computed(() =>\n\tgetBezierPath({\n\t\tsourceX: props.sourceX,\n\t\tsourceY: props.sourceY,\n\t\tsourcePosition: props.sourcePosition,\n\t\ttargetX: props.targetX,\n\t\ttargetY: props.targetY,\n\t\ttargetPosition: props.targetPosition,\n\t}),\n);\n</script>\n\n<template>\n\t<BaseEdge\n\t\t:id=\"id\"\n\t\t:style=\"edgeStyle\"\n\t\t:path=\"path[0]\"\n\t\t:marker-end=\"markerEnd\"\n\t\t:label=\"data?.label\"\n\t\t:label-x=\"path[1]\"\n\t\t:label-y=\"path[2]\"\n\t\t:label-style=\"{ fill: 'white' }\"\n\t\t:label-show-bg=\"true\"\n\t\t:label-bg-style=\"{ fill: 'red' }\"\n\t\t:label-bg-padding=\"[2, 4]\"\n\t\t:label-bg-border-radius=\"2\"\n\t/>\n</template>\n","<script lang=\"ts\" setup>\nimport type { CanvasConnection, CanvasElement } from '@/types';\nimport type { NodeDragEvent, Connection } from '@vue-flow/core';\nimport { VueFlow, PanelPosition } from '@vue-flow/core';\nimport { Background } from '@vue-flow/background';\nimport { Controls } from '@vue-flow/controls';\nimport { MiniMap } from '@vue-flow/minimap';\nimport CanvasNode from './elements/nodes/CanvasNode.vue';\nimport CanvasEdge from './elements/edges/CanvasEdge.vue';\nimport { useCssModule } from 'vue';\n\nconst $style = useCssModule();\n\nconst emit = defineEmits<{\n\t'update:modelValue': [elements: CanvasElement[]];\n\t'update:node:position': [id: string, position: { x: number; y: number }];\n\t'create:connection': [connection: Connection];\n}>();\n\nwithDefaults(\n\tdefineProps<{\n\t\tid?: string;\n\t\telements: CanvasElement[];\n\t\tconnections: CanvasConnection[];\n\t\tcontrolsPosition?: PanelPosition;\n\t}>(),\n\t{\n\t\tid: 'canvas',\n\t\telements: () => [],\n\t\tconnections: () => [],\n\t\tcontrolsPosition: PanelPosition.BottomLeft,\n\t},\n);\n\nfunction onNodeDragStop(e: NodeDragEvent) {\n\te.nodes.forEach((node) => {\n\t\temit('update:node:position', node.id, node.position);\n\t});\n}\n\nfunction onConnect(...args: unknown[]) {\n\temit('create:connection', args[0] as Connection);\n}\n</script>\n\n<template>\n\t<VueFlow\n\t\t:id=\"id\"\n\t\t:nodes=\"elements\"\n\t\t:edges=\"connections\"\n\t\t:apply-changes=\"false\"\n\t\tfit-view-on-init\n\t\tpan-on-scroll\n\t\t:min-zoom=\"0.2\"\n\t\t:max-zoom=\"2\"\n\t\tdata-test-id=\"canvas\"\n\t\t@node-drag-stop=\"onNodeDragStop\"\n\t\t@connect=\"onConnect\"\n\t>\n\t\t<template #node-canvas-node=\"canvasNodeProps\">\n\t\t\t<CanvasNode v-bind=\"canvasNodeProps\" />\n\t\t</template>\n\n\t\t<template #edge-canvas-edge=\"canvasEdgeProps\">\n\t\t\t<CanvasEdge v-bind=\"canvasEdgeProps\" />\n\t\t</template>\n\n\t\t<Background data-test-id=\"canvas-background\" pattern-color=\"#aaa\" :gap=\"16\" />\n\n\t\t<MiniMap data-test-id=\"canvas-minimap\" pannable />\n\n\t\t<Controls\n\t\t\tdata-test-id=\"canvas-controls\"\n\t\t\t:class=\"$style.canvasControls\"\n\t\t\t:position=\"controlsPosition\"\n\t\t></Controls>\n\t</VueFlow>\n</template>\n\n<style lang=\"scss\" module></style>\n\n<style lang=\"scss\">\n.vue-flow__controls {\n\tdisplay: flex;\n\tgap: var(--spacing-2xs);\n\tbox-shadow: none;\n}\n\n.vue-flow__controls-button {\n\twidth: 42px;\n\theight: 42px;\n\tborder: var(--border-base);\n\tborder-radius: var(--border-radius-base);\n\tpadding: 0;\n\ttransition-property: transform, background, border, color;\n\ttransition-duration: 300ms;\n\ttransition-timing-function: ease;\n\n\t&:hover {\n\t\tborder-color: var(--color-button-secondary-hover-active-border);\n\t\tbackground-color: var(--color-button-secondary-active-background);\n\t\ttransform: scale(1.1);\n\n\t\tsvg {\n\t\t\tfill: var(--color-primary);\n\t\t}\n\t}\n\n\tsvg {\n\t\tmax-height: 16px;\n\t\tmax-width: 16px;\n\t\ttransition-property: fill;\n\t\ttransition-duration: 300ms;\n\t\ttransition-timing-function: ease;\n\t}\n}\n</style>\n","import type { IConnections, INodeTypeDescription } from 'n8n-workflow';\nimport type { INodeUi } from '@/Interface';\nimport type { CanvasConnection, CanvasConnectionPortType, CanvasConnectionPort } from '@/types';\nimport { v4 as uuid } from 'uuid';\n\nexport function mapLegacyConnectionsToCanvasConnections(\n\tlegacyConnections: IConnections,\n\tnodes: INodeUi[],\n): CanvasConnection[] {\n\tconst mappedConnections: CanvasConnection[] = [];\n\n\tObject.keys(legacyConnections).forEach((fromNodeName) => {\n\t\tconst fromId = nodes.find((node) => node.name === fromNodeName)?.id;\n\t\tconst fromConnectionTypes = Object.keys(legacyConnections[fromNodeName]);\n\n\t\tfromConnectionTypes.forEach((fromConnectionType) => {\n\t\t\tconst fromPorts = legacyConnections[fromNodeName][fromConnectionType];\n\t\t\tfromPorts.forEach((toPorts, fromIndex) => {\n\t\t\t\ttoPorts.forEach((toPort) => {\n\t\t\t\t\tconst toId = nodes.find((node) => node.name === toPort.node)?.id;\n\t\t\t\t\tconst toConnectionType = toPort.type;\n\t\t\t\t\tconst toIndex = toPort.index;\n\n\t\t\t\t\tif (fromId && toId) {\n\t\t\t\t\t\tmappedConnections.push({\n\t\t\t\t\t\t\tid: `[${fromId}/${fromConnectionType}/${fromIndex}][${toId}/${toConnectionType}/${toIndex}]`,\n\t\t\t\t\t\t\tsource: fromId,\n\t\t\t\t\t\t\ttarget: toId,\n\t\t\t\t\t\t\tsourceHandle: `outputs/${fromConnectionType}/${fromIndex}`,\n\t\t\t\t\t\t\ttargetHandle: `inputs/${toConnectionType}/${toIndex}`,\n\t\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\t\tfromNodeName,\n\t\t\t\t\t\t\t\tsource: {\n\t\t\t\t\t\t\t\t\tindex: fromIndex,\n\t\t\t\t\t\t\t\t\ttype: fromConnectionType as CanvasConnectionPortType,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\ttarget: {\n\t\t\t\t\t\t\t\t\tindex: toIndex,\n\t\t\t\t\t\t\t\t\ttype: toConnectionType as CanvasConnectionPortType,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t});\n\t\t});\n\t});\n\n\treturn mappedConnections;\n}\n\nexport function mapLegacyEndpointsToCanvasConnectionPort(\n\tendpoints: INodeTypeDescription['inputs'],\n): CanvasConnectionPort[] {\n\tif (typeof endpoints === 'string') {\n\t\tconsole.warn('Node endpoints have not been evaluated', endpoints);\n\t\treturn [];\n\t}\n\n\treturn endpoints.map((endpoint, endpointIndex) => {\n\t\tconst type = typeof endpoint === 'string' ? endpoint : endpoint.type;\n\t\tconst label = typeof endpoint === 'string' ? undefined : endpoint.displayName;\n\t\tconst index =\n\t\t\tendpoints\n\t\t\t\t.slice(0, endpointIndex + 1)\n\t\t\t\t.filter((e) => (typeof e === 'string' ? e : e.type) === type).length - 1;\n\t\tconst required = typeof endpoint === 'string' ? false : endpoint.required;\n\n\t\treturn {\n\t\t\ttype,\n\t\t\tindex,\n\t\t\tlabel,\n\t\t\t...(required ? { required } : {}),\n\t\t};\n\t});\n}\n\nexport function getUniqueNodeName(name: string, existingNames: Set<string>): string {\n\tif (!existingNames.has(name)) {\n\t\treturn name;\n\t}\n\n\tfor (let i = 1; i < 100; i++) {\n\t\tconst newName = `${name} ${i}`;\n\t\tif (!existingNames.has(newName)) {\n\t\t\treturn newName;\n\t\t}\n\t}\n\n\treturn `${name} ${uuid()}`;\n}\n","import { useI18n } from '@/composables/useI18n';\nimport { useNodeTypesStore } from '@/stores/nodeTypes.store';\nimport type { Ref } from 'vue';\nimport { computed } from 'vue';\nimport type {\n\tCanvasConnection,\n\tCanvasConnectionPort,\n\tCanvasElement,\n\tCanvasElementData,\n} from '@/types';\nimport {\n\tmapLegacyConnectionsToCanvasConnections,\n\tmapLegacyEndpointsToCanvasConnectionPort,\n} from '@/utils/canvasUtilsV2';\nimport type { Workflow } from 'n8n-workflow';\nimport { NodeHelpers } from 'n8n-workflow';\nimport type { IWorkflowDb } from '@/Interface';\n\nexport function useCanvasMapping({\n\tworkflow,\n\tworkflowObject,\n}: {\n\tworkflow: Ref<IWorkflowDb>;\n\tworkflowObject: Ref<Workflow>;\n}) {\n\tconst locale = useI18n();\n\tconst nodeTypesStore = useNodeTypesStore();\n\n\tconst renderTypeByNodeType = computed(\n\t\t() =>\n\t\t\tworkflow.value.nodes.reduce<Record<string, CanvasElementData['renderType']>>((acc, node) => {\n\t\t\t\tlet renderType: CanvasElementData['renderType'] = 'default';\n\t\t\t\tswitch (true) {\n\t\t\t\t\tcase nodeTypesStore.isTriggerNode(node.type):\n\t\t\t\t\t\trenderType = 'trigger';\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase nodeTypesStore.isConfigNode(workflowObject.value, node, node.type):\n\t\t\t\t\t\trenderType = 'configuration';\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase nodeTypesStore.isConfigurableNode(workflowObject.value, node, node.type):\n\t\t\t\t\t\trenderType = 'configurable';\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tacc[node.type] = renderType;\n\t\t\t\treturn acc;\n\t\t\t}, {}) ?? {},\n\t);\n\n\tconst nodeInputsById = computed(() =>\n\t\tworkflow.value.nodes.reduce<Record<string, CanvasConnectionPort[]>>((acc, node) => {\n\t\t\tconst nodeTypeDescription = nodeTypesStore.getNodeType(node.type);\n\t\t\tconst workflowObjectNode = workflowObject.value.getNode(node.name);\n\n\t\t\tacc[node.id] =\n\t\t\t\tworkflowObjectNode && nodeTypeDescription\n\t\t\t\t\t? mapLegacyEndpointsToCanvasConnectionPort(\n\t\t\t\t\t\t\tNodeHelpers.getNodeInputs(\n\t\t\t\t\t\t\t\tworkflowObject.value,\n\t\t\t\t\t\t\t\tworkflowObjectNode,\n\t\t\t\t\t\t\t\tnodeTypeDescription,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t)\n\t\t\t\t\t: [];\n\n\t\t\treturn acc;\n\t\t}, {}),\n\t);\n\n\tconst nodeOutputsById = computed(() =>\n\t\tworkflow.value.nodes.reduce<Record<string, CanvasConnectionPort[]>>((acc, node) => {\n\t\t\tconst nodeTypeDescription = nodeTypesStore.getNodeType(node.type);\n\t\t\tconst workflowObjectNode = workflowObject.value.getNode(node.name);\n\n\t\t\tacc[node.id] =\n\t\t\t\tworkflowObjectNode && nodeTypeDescription\n\t\t\t\t\t? mapLegacyEndpointsToCanvasConnectionPort(\n\t\t\t\t\t\t\tNodeHelpers.getNodeOutputs(\n\t\t\t\t\t\t\t\tworkflowObject.value,\n\t\t\t\t\t\t\t\tworkflowObjectNode,\n\t\t\t\t\t\t\t\tnodeTypeDescription,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t)\n\t\t\t\t\t: [];\n\n\t\t\treturn acc;\n\t\t}, {}),\n\t);\n\n\tconst elements = computed<CanvasElement[]>(() => [\n\t\t...workflow.value.nodes.map<CanvasElement>((node) => {\n\t\t\tconst data: CanvasElementData = {\n\t\t\t\tid: node.id,\n\t\t\t\ttype: node.type,\n\t\t\t\ttypeVersion: node.typeVersion,\n\t\t\t\tinputs: nodeInputsById.value[node.id] ?? [],\n\t\t\t\toutputs: nodeOutputsById.value[node.id] ?? [],\n\t\t\t\trenderType: renderTypeByNodeType.value[node.type] ?? 'default',\n\t\t\t};\n\n\t\t\treturn {\n\t\t\t\tid: node.id,\n\t\t\t\tlabel: node.name,\n\t\t\t\ttype: 'canvas-node',\n\t\t\t\tposition: { x: node.position[0], y: node.position[1] },\n\t\t\t\tdata,\n\t\t\t};\n\t\t}),\n\t]);\n\n\tconst connections = computed<CanvasConnection[]>(() => {\n\t\tconst mappedConnections = mapLegacyConnectionsToCanvasConnections(\n\t\t\tworkflow.value.connections ?? [],\n\t\t\tworkflow.value.nodes ?? [],\n\t\t);\n\n\t\treturn mappedConnections.map((connection) => {\n\t\t\tconst type = getConnectionType(connection);\n\t\t\tconst label = getConnectionLabel(connection);\n\n\t\t\treturn {\n\t\t\t\t...connection,\n\t\t\t\ttype,\n\t\t\t\tlabel,\n\t\t\t};\n\t\t});\n\t});\n\n\tfunction getConnectionType(_: CanvasConnection): string {\n\t\treturn 'canvas-edge';\n\t}\n\n\tfunction getConnectionLabel(connection: CanvasConnection): string {\n\t\tconst pinData = workflow.value.pinData?.[connection.data?.fromNodeName ?? ''];\n\n\t\tif (pinData?.length) {\n\t\t\treturn locale.baseText('ndv.output.items', {\n\t\t\t\tadjustToNumber: pinData.length,\n\t\t\t\tinterpolate: { count: String(pinData.length) },\n\t\t\t});\n\t\t}\n\n\t\treturn '';\n\t}\n\n\treturn {\n\t\tconnections,\n\t\telements,\n\t};\n}\n","<script setup lang=\"ts\">\nimport Canvas from '@/components/canvas/Canvas.vue';\nimport { toRef, useCssModule } from 'vue';\nimport type { Workflow } from 'n8n-workflow';\nimport type { IWorkflowDb } from '@/Interface';\nimport { useCanvasMapping } from '@/composables/useCanvasMapping';\n\nconst props = defineProps<{\n\tid?: string;\n\tworkflow: IWorkflowDb;\n\tworkflowObject: Workflow;\n}>();\n\nconst $style = useCssModule();\n\nconst workflow = toRef(props, 'workflow');\nconst workflowObject = toRef(props, 'workflowObject');\n\nconst { elements, connections } = useCanvasMapping({ workflow, workflowObject });\n</script>\n\n<template>\n\t<div :class=\"$style.wrapper\">\n\t\t<div :class=\"$style.canvas\">\n\t\t\t<Canvas v-if=\"workflow\" :elements=\"elements\" :connections=\"connections\" v-bind=\"$attrs\" />\n\t\t</div>\n\t\t<slot />\n\t</div>\n</template>\n\n<style lang=\"scss\" module>\n.wrapper {\n\tdisplay: block;\n\tposition: relative;\n\twidth: 100%;\n\theight: 100%;\n\toverflow: hidden;\n}\n\n.canvas {\n\twidth: 100%;\n\theight: 100%;\n\tposition: relative;\n\tdisplay: block;\n}\n\n.executionButtons {\n\tposition: absolute;\n\tdisplay: flex;\n\tjustify-content: center;\n\talign-items: center;\n\tleft: 50%;\n\ttransform: translateX(-50%);\n\tbottom: var(--spacing-l);\n\twidth: auto;\n\n\t@media (max-width: $breakpoint-2xs) {\n\t\tbottom: 150px;\n\t}\n\n\tbutton {\n\t\tdisplay: flex;\n\t\tjustify-content: center;\n\t\talign-items: center;\n\t\tmargin-left: 0.625rem;\n\n\t\t&:first-child {\n\t\t\tmargin: 0;\n\t\t}\n\t}\n}\n</style>\n","<script setup lang=\"ts\">\nimport KeyboardShortcutTooltip from '@/components/KeyboardShortcutTooltip.vue';\nimport { computed } from 'vue';\nimport { useI18n } from '@/composables/useI18n';\nimport { useUIStore } from '@/stores/ui.store';\n\ndefineEmits(['click']);\n\nconst uiStore = useUIStore();\nconst locale = useI18n();\n\nconst workflowRunning = computed(() => uiStore.isActionActive('workflowRunning'));\n\nconst runButtonText = computed(() => {\n\tif (!workflowRunning.value) {\n\t\treturn locale.baseText('nodeView.runButtonText.executeWorkflow');\n\t}\n\n\treturn locale.baseText('nodeView.runButtonText.executingWorkflow');\n});\n</script>\n\n<template>\n\t<KeyboardShortcutTooltip :label=\"runButtonText\" :shortcut=\"{ metaKey: true, keys: ['↵'] }\">\n\t\t<N8nButton\n\t\t\t:loading=\"workflowRunning\"\n\t\t\t:label=\"runButtonText\"\n\t\t\tsize=\"large\"\n\t\t\ticon=\"flask\"\n\t\t\ttype=\"primary\"\n\t\t\tdata-test-id=\"execute-workflow-button\"\n\t\t\t@click.stop=\"$emit('click', $event)\"\n\t\t/>\n\t</KeyboardShortcutTooltip>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, defineAsyncComponent, onMounted, ref, useCssModule } from 'vue';\nimport { useRoute, useRouter } from 'vue-router';\nimport WorkflowCanvas from '@/components/canvas/WorkflowCanvas.vue';\nimport { useNodeTypesStore } from '@/stores/nodeTypes.store';\nimport { useUIStore } from '@/stores/ui.store';\nimport CanvasExecuteWorkflowButton from '@/components/canvas/elements/buttons/CanvasExecuteWorkflowButton.vue';\nimport { useI18n } from '@/composables/useI18n';\nimport { useWorkflowsStore } from '@/stores/workflows.store';\nimport { useRunWorkflow } from '@/composables/useRunWorkflow';\nimport type {\n\tAddedNodesAndConnections,\n\tINodeUi,\n\tITag,\n\tToggleNodeCreatorOptions,\n\tXYPosition,\n} from '@/Interface';\nimport useWorkflowsEEStore from '@/stores/workflows.ee.store';\nimport { useTagsStore } from '@/stores/tags.store';\nimport type { Connection } from '@vue-flow/core';\nimport type { CanvasElement } from '@/types';\nimport {\n\tEnterpriseEditionFeature,\n\tAI_NODE_CREATOR_VIEW,\n\tREGULAR_NODE_CREATOR_VIEW,\n\tTRIGGER_NODE_CREATOR_VIEW,\n\tVIEWS,\n} from '@/constants';\nimport { useSourceControlStore } from '@/stores/sourceControl.store';\nimport { useNodeCreatorStore } from '@/stores/nodeCreator.store';\nimport { useTelemetry } from '@/composables/useTelemetry';\nimport { useExternalHooks } from '@/composables/useExternalHooks';\nimport * as NodeViewUtils from '@/utils/nodeViewUtils';\nimport type { INodeTypeDescription } from 'n8n-workflow';\nimport { NodeConnectionType } from 'n8n-workflow';\nimport { useToast } from '@/composables/useToast';\nimport { v4 as uuid } from 'uuid';\nimport { useSettingsStore } from '@/stores/settings.store';\nimport { useCredentialsStore } from '@/stores/credentials.store';\nimport useEnvironmentsStore from '@/stores/environments.ee.store';\nimport { useExternalSecretsStore } from '@/stores/externalSecrets.ee.store';\nimport { useRootStore } from '@/stores/n8nRoot.store';\nimport { useCollaborationStore } from '@/stores/collaboration.store';\nimport { getUniqueNodeName } from '@/utils/canvasUtilsV2';\n\nconst NodeCreation = defineAsyncComponent(\n\tasync () => await import('@/components/Node/NodeCreation.vue'),\n);\n\nconst $style = useCssModule();\n\nconst router = useRouter();\nconst route = useRoute();\nconst i18n = useI18n();\nconst telemetry = useTelemetry();\nconst externalHooks = useExternalHooks();\nconst toast = useToast();\n\nconst nodeTypesStore = useNodeTypesStore();\nconst uiStore = useUIStore();\nconst workflowsStore = useWorkflowsStore();\nconst workflowsEEStore = useWorkflowsEEStore();\nconst tagsStore = useTagsStore();\nconst sourceControlStore = useSourceControlStore();\nconst nodeCreatorStore = useNodeCreatorStore();\nconst settingsStore = useSettingsStore();\nconst credentialsStore = useCredentialsStore();\nconst environmentsStore = useEnvironmentsStore();\nconst externalSecretsStore = useExternalSecretsStore();\nconst rootStore = useRootStore();\nconst collaborationStore = useCollaborationStore();\n\nconst { runWorkflow } = useRunWorkflow({ router });\n\nconst isLoading = ref(true);\nconst readOnlyNotification = ref<null | { visible: boolean }>(null);\n\nconst workflowId = computed<string>(() => route.params.workflowId as string);\nconst workflow = computed(() => workflowsStore.workflowsById[workflowId.value]);\n\nconst editableWorkflow = computed(() => workflowsStore.workflow);\nconst editableWorkflowObject = computed(() => workflowsStore.getCurrentWorkflow());\n\nconst isDemoRoute = computed(() => route.name === VIEWS.DEMO);\nconst isReadOnlyRoute = computed(() => route?.meta?.readOnlyCanvas === true);\nconst isReadOnlyEnvironment = computed(() => {\n\treturn sourceControlStore.preferences.branchReadOnly;\n});\n\nconst triggerNodes = computed<INodeUi[]>(() => {\n\treturn workflowsStore.workflowTriggerNodes;\n});\n\nconst isCanvasAddButtonVisible = computed(() => {\n\treturn (\n\t\ttriggerNodes.value.length > 0 &&\n\t\t!isLoading.value &&\n\t\t!isDemoRoute.value &&\n\t\t!isReadOnlyEnvironment.value\n\t);\n});\n\nonMounted(() => {\n\tvoid initialize();\n});\n\nasync function initialize() {\n\tisLoading.value = true;\n\n\tconst loadPromises: Array<Promise<unknown>> = [\n\t\tnodeTypesStore.getNodeTypes(),\n\t\tworkflowsStore.fetchWorkflow(workflowId.value),\n\t];\n\n\tif (!settingsStore.isPreviewMode && !isDemoRoute.value) {\n\t\tloadPromises.push(\n\t\t\tworkflowsStore.fetchActiveWorkflows(),\n\t\t\tcredentialsStore.fetchAllCredentials(),\n\t\t\tcredentialsStore.fetchCredentialTypes(true),\n\t\t);\n\n\t\tif (settingsStore.isEnterpriseFeatureEnabled(EnterpriseEditionFeature.Variables)) {\n\t\t\tloadPromises.push(environmentsStore.fetchAllVariables());\n\t\t}\n\n\t\tif (settingsStore.isEnterpriseFeatureEnabled(EnterpriseEditionFeature.ExternalSecrets)) {\n\t\t\tloadPromises.push(externalSecretsStore.fetchAllSecrets());\n\t\t}\n\t}\n\n\ttry {\n\t\tawait Promise.all(loadPromises);\n\t} catch (error) {\n\t\treturn toast.showError(\n\t\t\terror,\n\t\t\ti18n.baseText('nodeView.showError.mounted1.title'),\n\t\t\ti18n.baseText('nodeView.showError.mounted1.message') + ':',\n\t\t);\n\t}\n\n\tinitializeEditableWorkflow(workflowId.value);\n\n\tif (window.parent) {\n\t\twindow.parent.postMessage(\n\t\t\tJSON.stringify({ command: 'n8nReady', version: rootStore.versionCli }),\n\t\t\t'*',\n\t\t);\n\t}\n\n\tisLoading.value = false;\n}\n\n// @TODO Maybe move this to the store\nfunction initializeEditableWorkflow(id: string) {\n\tconst targetWorkflow = workflowsStore.workflowsById[id];\n\n\tworkflowsStore.addWorkflow(targetWorkflow);\n\tworkflowsStore.setWorkflow(targetWorkflow);\n\tworkflowsStore.setActive(targetWorkflow.active || false);\n\tworkflowsStore.setWorkflowId(targetWorkflow.id);\n\tworkflowsStore.setWorkflowName({ newName: targetWorkflow.name, setStateDirty: false });\n\tworkflowsStore.setWorkflowSettings(targetWorkflow.settings ?? {});\n\tworkflowsStore.setWorkflowPinData(targetWorkflow.pinData ?? {});\n\tworkflowsStore.setWorkflowVersionId(targetWorkflow.versionId);\n\tworkflowsStore.setWorkflowMetadata(targetWorkflow.meta);\n\tif (targetWorkflow.usedCredentials) {\n\t\tworkflowsStore.setUsedCredentials(targetWorkflow.usedCredentials);\n\t}\n\n\tconst tags = (targetWorkflow.tags ?? []) as ITag[];\n\tconst tagIds = tags.map((tag) => tag.id);\n\tworkflowsStore.setWorkflowTagIds(tagIds || []);\n\ttagsStore.upsertTags(tags);\n\n\t// @TODO Figure out a better way to handle this. Maybe show a message on why the state becomes dirty\n\t// if (!this.credentialsUpdated) {\n\t// \tthis.uiStore.stateIsDirty = false;\n\t// }\n\n\tvoid externalHooks.run('workflow.open', {\n\t\tworkflowId: workflow.value.id,\n\t\tworkflowName: workflow.value.name,\n\t});\n\n\t// @TODO Figure out a better way to handle this\n\t// if (selectedExecution?.workflowId !== workflow.id) {\n\t// \tthis.executionsStore.activeExecution = null;\n\t// \tworkflowsStore.currentWorkflowExecutions = [];\n\t// } else {\n\t// \tthis.executionsStore.activeExecution = selectedExecution;\n\t// }\n\n\tcollaborationStore.notifyWorkflowOpened(workflow.value.id);\n}\n\nasync function onRunWorkflow() {\n\tawait runWorkflow({});\n}\n\n/**\n * Map new node position format to the old one and update the store\n *\n * @param id\n * @param position\n */\nfunction onNodePositionUpdate(id: string, position: CanvasElement['position']) {\n\tworkflowsStore.setNodePosition(id, [position.x, position.y]);\n}\n\n/**\n * Map new node connection format to the old one and add it to the store\n *\n * @param connection\n */\nfunction onCreateNodeConnection(connection: Connection) {\n\t// Output\n\tconst sourceNodeId = connection.source;\n\tconst sourceNode = workflowsStore.getNodeById(sourceNodeId);\n\tconst sourceNodeName = sourceNode?.name ?? '';\n\tconst [, sourceType, sourceIndex] = (connection.sourceHandle ?? '').split('/');\n\n\t// Input\n\tconst targetNodeId = connection.target;\n\tconst targetNode = workflowsStore.getNodeById(targetNodeId);\n\tconst targetNodeName = targetNode?.name ?? '';\n\tconst [, targetType, targetIndex] = (connection.targetHandle ?? '').split('/');\n\n\tif (sourceNode && targetNode && !checkIfNodeConnectionIsAllowed(sourceNode, targetNode)) {\n\t\treturn;\n\t}\n\n\tworkflowsStore.addConnection({\n\t\tconnection: [\n\t\t\t{\n\t\t\t\tnode: sourceNodeName,\n\t\t\t\ttype: sourceType,\n\t\t\t\tindex: parseInt(sourceIndex, 10),\n\t\t\t},\n\t\t\t{\n\t\t\t\tnode: targetNodeName,\n\t\t\t\ttype: targetType,\n\t\t\t\tindex: parseInt(targetIndex, 10),\n\t\t\t},\n\t\t],\n\t});\n\n\tuiStore.stateIsDirty = true;\n}\n\n// @TODO Figure out a way to improve this\nfunction checkIfNodeConnectionIsAllowed(sourceNode: INodeUi, targetNode: INodeUi): boolean {\n\t// const targetNodeType = nodeTypesStore.getNodeType(\n\t// \ttargetNode.type,\n\t// \ttargetNode.typeVersion,\n\t// );\n\t//\n\t// if (targetNodeType?.inputs?.length) {\n\t// \tconst workflow = this.workflowHelpers.getCurrentWorkflow();\n\t// \tconst workflowNode = workflow.getNode(targetNode.name);\n\t// \tlet inputs: Array<ConnectionTypes | INodeInputConfiguration> = [];\n\t// \tif (targetNodeType) {\n\t// \t\tinputs = NodeHelpers.getNodeInputs(workflow, workflowNode, targetNodeType);\n\t// \t}\n\t//\n\t// \tfor (const input of inputs || []) {\n\t// \t\tif (typeof input === 'string' || input.type !== targetInfoType || !input.filter) {\n\t// \t\t\t// No filters defined or wrong connection type\n\t// \t\t\tcontinue;\n\t// \t\t}\n\t//\n\t// \t\tif (input.filter.nodes.length) {\n\t// \t\t\tif (!input.filter.nodes.includes(sourceNode.type)) {\n\t// \t\t\t\tthis.dropPrevented = true;\n\t// \t\t\t\tthis.showToast({\n\t// \t\t\t\t\ttitle: this.$locale.baseText('nodeView.showError.nodeNodeCompatible.title'),\n\t// \t\t\t\t\tmessage: this.$locale.baseText('nodeView.showError.nodeNodeCompatible.message', {\n\t// \t\t\t\t\t\tinterpolate: { sourceNodeName: sourceNode.name, targetNodeName: targetNode.name },\n\t// \t\t\t\t\t}),\n\t// \t\t\t\t\ttype: 'error',\n\t// \t\t\t\t\tduration: 5000,\n\t// \t\t\t\t});\n\t// \t\t\t\treturn false;\n\t// \t\t\t}\n\t// \t\t}\n\t// \t}\n\t// }\n\treturn true;\n}\n\nfunction onToggleNodeCreator({\n\tsource,\n\tcreateNodeActive,\n\tnodeCreatorView,\n}: ToggleNodeCreatorOptions) {\n\tif (createNodeActive === uiStore.isCreateNodeActive) {\n\t\treturn;\n\t}\n\n\tif (!nodeCreatorView) {\n\t\tnodeCreatorView =\n\t\t\ttriggerNodes.value.length > 0 ? REGULAR_NODE_CREATOR_VIEW : TRIGGER_NODE_CREATOR_VIEW;\n\t}\n\t// Default to the trigger tab in node creator if there's no trigger node yet\n\tnodeCreatorStore.setSelectedView(nodeCreatorView);\n\n\tlet mode;\n\tswitch (nodeCreatorStore.selectedView) {\n\t\tcase AI_NODE_CREATOR_VIEW:\n\t\t\tmode = 'ai';\n\t\t\tbreak;\n\t\tcase REGULAR_NODE_CREATOR_VIEW:\n\t\t\tmode = 'regular';\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tmode = 'regular';\n\t}\n\n\tuiStore.isCreateNodeActive = createNodeActive;\n\tif (createNodeActive && source) {\n\t\tnodeCreatorStore.setOpenSource(source);\n\t}\n\n\tvoid externalHooks.run('nodeView.createNodeActiveChanged', {\n\t\tsource,\n\t\tmode,\n\t\tcreateNodeActive,\n\t});\n\n\ttelemetry.trackNodesPanel('nodeView.createNodeActiveChanged', {\n\t\tsource,\n\t\tmode,\n\t\tcreateNodeActive,\n\t\tworkflow_id: workflowId.value,\n\t});\n}\n\nasync function onAddNodes(\n\t{ nodes, connections }: AddedNodesAndConnections,\n\tdragAndDrop = false,\n\tposition?: XYPosition,\n) {\n\tlet currentPosition = position;\n\tfor (const { type, name, position: nodePosition, isAutoAdd, openDetail } of nodes) {\n\t\tconst node = await addNode(\n\t\t\t{\n\t\t\t\tname,\n\t\t\t\ttype,\n\t\t\t\tposition: nodePosition ?? currentPosition,\n\t\t\t},\n\t\t\t{\n\t\t\t\tdragAndDrop,\n\t\t\t\topenNDV: openDetail ?? false,\n\t\t\t\ttrackHistory: true,\n\t\t\t\tisAutoAdd,\n\t\t\t},\n\t\t);\n\n\t\tconst lastAddedNode = editableWorkflow.value.nodes[editableWorkflow.value.nodes.length - 1];\n\t\tcurrentPosition = [\n\t\t\tlastAddedNode.position[0] + NodeViewUtils.NODE_SIZE * 2 + NodeViewUtils.GRID_SIZE,\n\t\t\tlastAddedNode.position[1],\n\t\t];\n\t}\n\n\tconst newNodesOffset = editableWorkflow.value.nodes.length - nodes.length;\n\tfor (const { from, to } of connections) {\n\t\tconst fromNode = editableWorkflow.value.nodes[newNodesOffset + from.nodeIndex];\n\t\tconst toNode = editableWorkflow.value.nodes[newNodesOffset + to.nodeIndex];\n\n\t\tonCreateNodeConnection({\n\t\t\tsource: fromNode.id,\n\t\t\tsourceHandle: `outputs/${NodeConnectionType.Main}/${from.outputIndex ?? 0}`,\n\t\t\ttarget: toNode.id,\n\t\t\ttargetHandle: `inputs/${NodeConnectionType.Main}/${to.inputIndex ?? 0}`,\n\t\t});\n\t}\n\n\t// @TODO Implement this\n\t// const lastAddedNode = editableWorkflow.value.nodes[editableWorkflow.value.nodes.length - 1];\n\t// const workflow = editableWorkflowObject.value;\n\t// const lastNodeInputs = workflow.getParentNodesByDepth(lastAddedNode.name, 1);\n\t//\n\t// // If the last added node has multiple inputs, move them down\n\t// if (lastNodeInputs.length > 1) {\n\t// \tlastNodeInputs.slice(1).forEach((node, index) => {\n\t// \t\tconst nodeUi = workflowsStore.getNodeByName(node.name);\n\t// \t\tif (!nodeUi) return;\n\t//\n\t// \t\t// onMoveNode({\n\t// \t\t// \tnodeName: nodeUi.name,\n\t// \t\t// \tposition: [nodeUi.position[0], nodeUi.position[1] + 100 * (index + 1)],\n\t// \t\t// });\n\t// \t});\n\t// }\n}\n\ntype AddNodeData = {\n\tname?: string;\n\ttype: string;\n\tposition?: XYPosition;\n};\n\ntype AddNodeOptions = {\n\tdragAndDrop?: boolean;\n\topenNDV?: boolean;\n\ttrackHistory?: boolean;\n\tisAutoAdd?: boolean;\n};\n\nasync function addNode(node: AddNodeData, options: AddNodeOptions): Promise<INodeUi | undefined> {\n\tif (!checkIfEditingIsAllowed()) {\n\t\treturn;\n\t}\n\n\tconst newNodeData = await createNodeWithDefaultCredentials(node);\n\tif (!newNodeData) {\n\t\treturn;\n\t}\n\n\t/**\n\t * @TODO Check if maximum node type limit reached\n\t */\n\n\tnewNodeData.name = getUniqueNodeName(newNodeData.name, workflowsStore.canvasNames);\n\n\tworkflowsStore.addNode(newNodeData);\n\n\t// @TODO Figure out why this is needed and if we can do better...\n\t// this.matchCredentials(node);\n\n\t// const lastSelectedNode = uiStore.getLastSelectedNode;\n\t// const lastSelectedNodeOutputIndex = uiStore.lastSelectedNodeOutputIndex;\n\t// const lastSelectedNodeEndpointUuid = uiStore.lastSelectedNodeEndpointUuid;\n\t// const lastSelectedConnection = canvasStore.lastSelectedConnection;\n\t//\n\t// historyStore.startRecordingUndo();\n\t//\n\t// const newNodeData = await injectNode(\n\t// \tnodeTypeName,\n\t// \toptions,\n\t// \tshowDetail,\n\t// \ttrackHistory,\n\t// \tisAutoAdd,\n\t// );\n\t// if (!newNodeData) {\n\t// \treturn;\n\t// }\n\t//\n\t// const outputIndex = lastSelectedNodeOutputIndex || 0;\n\t// const targetEndpoint = lastSelectedNodeEndpointUuid || '';\n\t//\n\t// // Handle connection of scoped_endpoint types\n\t// if (lastSelectedNodeEndpointUuid && !isAutoAdd) {\n\t// \tconst lastSelectedEndpoint = this.instance.getEndpoint(lastSelectedNodeEndpointUuid);\n\t// \tif (\n\t// \t\tlastSelectedEndpoint &&\n\t// \t\tthis.checkNodeConnectionAllowed(\n\t// \t\t\tlastSelectedNode,\n\t// \t\t\tnewNodeData,\n\t// \t\t\tlastSelectedEndpoint.scope as NodeConnectionType,\n\t// \t\t)\n\t// \t) {\n\t// \t\tconst connectionType = lastSelectedEndpoint.scope as ConnectionTypes;\n\t// \t\tconst newNodeElement = this.instance.getManagedElement(newNodeData.id);\n\t// \t\tconst newNodeConnections = this.instance.getEndpoints(newNodeElement);\n\t// \t\tconst viableConnection = newNodeConnections.find((conn) => {\n\t// \t\t\treturn (\n\t// \t\t\t\tconn.scope === connectionType &&\n\t// \t\t\t\tlastSelectedEndpoint.parameters.connection !== conn.parameters.connection\n\t// \t\t\t);\n\t// \t\t});\n\t//\n\t// \t\tthis.instance?.connect({\n\t// \t\t\tuuids: [targetEndpoint, viableConnection?.uuid || ''],\n\t// \t\t\tdetachable: !this.isReadOnlyRoute && !this.readOnlyEnv,\n\t// \t\t});\n\t// \t\tthis.historyStore.stopRecordingUndo();\n\t// \t\treturn;\n\t// \t}\n\t// }\n\t// If a node is last selected then connect between the active and its child ones\n\t// if (lastSelectedNode && !isAutoAdd) {\n\t// \tawait this.$nextTick();\n\t//\n\t// \tif (lastSelectedConnection?.__meta) {\n\t// \t\tthis.__deleteJSPlumbConnection(lastSelectedConnection, trackHistory);\n\t//\n\t// \t\tconst targetNodeName = lastSelectedConnection.__meta.targetNodeName;\n\t// \t\tconst targetOutputIndex = lastSelectedConnection.__meta.targetOutputIndex;\n\t// \t\tthis.connectTwoNodes(\n\t// \t\t\tnewNodeData.name,\n\t// \t\t\t0,\n\t// \t\t\ttargetNodeName,\n\t// \t\t\ttargetOutputIndex,\n\t// \t\t\tNodeConnectionType.Main,\n\t// \t\t);\n\t// \t}\n\t//\n\t// \t// Connect active node to the newly created one\n\t// \tthis.connectTwoNodes(\n\t// \t\tlastSelectedNode.name,\n\t// \t\toutputIndex,\n\t// \t\tnewNodeData.name,\n\t// \t\t0,\n\t// \t\tNodeConnectionType.Main,\n\t// \t);\n\t// }\n\t// this.historyStore.stopRecordingUndo();\n\n\treturn newNodeData;\n}\n\nasync function createNodeWithDefaultCredentials(node: Partial<INodeUi>) {\n\tconst nodeTypeDescription = nodeTypesStore.getNodeType(\n\t\tnode.type as string,\n\t) as INodeTypeDescription;\n\n\tlet nodeVersion = nodeTypeDescription.defaultVersion;\n\tif (nodeVersion === undefined) {\n\t\tnodeVersion = Array.isArray(nodeTypeDescription.version)\n\t\t\t? nodeTypeDescription.version.slice(-1)[0]\n\t\t\t: nodeTypeDescription.version;\n\t}\n\n\tconst newNodeData: INodeUi = {\n\t\tid: uuid(),\n\t\tname: node.name ?? (nodeTypeDescription.defaults.name as string),\n\t\ttype: nodeTypeDescription.name,\n\t\ttypeVersion: nodeVersion,\n\t\tposition: node.position ?? [0, 0],\n\t\tparameters: {},\n\t};\n\n\t/**\n\t * @TODO Implement this\n\t */\n\n\t// // Load the default parameter values because only values which differ\n\t// // from the defaults get saved\n\t// if (nodeType !== null) {\n\t// \tlet nodeParameters = null;\n\t// \ttry {\n\t// \t\tnodeParameters = NodeHelpers.getNodeParameters(\n\t// \t\t\tnodeType.properties,\n\t// \t\t\tnode.parameters,\n\t// \t\t\ttrue,\n\t// \t\t\tfalse,\n\t// \t\t\tnode,\n\t// \t\t);\n\t// \t} catch (e) {\n\t// \t\tconsole.error(\n\t// \t\t\tthis.$locale.baseText('nodeView.thereWasAProblemLoadingTheNodeParametersOfNode') +\n\t// \t\t\t`: \"${node.name}\"`,\n\t// \t\t);\n\t// \t\tconsole.error(e);\n\t// \t}\n\t// \tnode.parameters = nodeParameters !== null ? nodeParameters : {};\n\t//\n\t// \t// if it's a webhook and the path is empty set the UUID as the default path\n\t// \tif (\n\t// \t\t[WEBHOOK_NODE_TYPE, FORM_TRIGGER_NODE_TYPE].includes(node.type) &&\n\t// \t\tnode.parameters.path === ''\n\t// \t) {\n\t// \t\tnode.parameters.path = node.webhookId as string;\n\t// \t}\n\t// }\n\t// const credentialPerType = nodeTypeData.credentials\n\t// \t?.map((type) => credentialsStore.getUsableCredentialByType(type.name))\n\t// \t.flat();\n\t//\n\t// if (credentialPerType && credentialPerType.length === 1) {\n\t// \tconst defaultCredential = credentialPerType[0];\n\t//\n\t// \tconst selectedCredentials = credentialsStore.getCredentialById(defaultCredential.id);\n\t// \tconst selected = { id: selectedCredentials.id, name: selectedCredentials.name };\n\t// \tconst credentials = {\n\t// \t\t[defaultCredential.type]: selected,\n\t// \t};\n\t//\n\t// \tawait loadNodesProperties(\n\t// \t\t[newNodeData].map((node) => ({ name: node.type, version: node.typeVersion })),\n\t// \t);\n\t//\n\t// \tconst nodeType = nodeTypesStore.getNodeType(newNodeData.type, newNodeData.typeVersion);\n\t// \tconst nodeParameters = NodeHelpers.getNodeParameters(\n\t// \t\tnodeType?.properties ?? [],\n\t// \t\t{},\n\t// \t\ttrue,\n\t// \t\tfalse,\n\t// \t\tnewNodeData,\n\t// \t);\n\t//\n\t// \tif (nodeTypeData.credentials) {\n\t// \t\tconst authentication = nodeTypeData.credentials.find(\n\t// \t\t\t(type) => type.name === defaultCredential.type,\n\t// \t\t);\n\t// \t\tif (authentication?.displayOptions?.hide) {\n\t// \t\t\treturn newNodeData;\n\t// \t\t}\n\t//\n\t// \t\tconst authDisplayOptions = authentication?.displayOptions?.show;\n\t// \t\tif (!authDisplayOptions) {\n\t// \t\t\tnewNodeData.credentials = credentials;\n\t// \t\t\treturn newNodeData;\n\t// \t\t}\n\t//\n\t// \t\tif (Object.keys(authDisplayOptions).length === 1 && authDisplayOptions.authentication) {\n\t// \t\t\t// ignore complex case when there's multiple dependencies\n\t// \t\t\tnewNodeData.credentials = credentials;\n\t//\n\t// \t\t\tlet parameters: { [key: string]: string } = {};\n\t// \t\t\tfor (const displayOption of Object.keys(authDisplayOptions)) {\n\t// \t\t\t\tif (nodeParameters && !nodeParameters[displayOption]) {\n\t// \t\t\t\t\tparameters = {};\n\t// \t\t\t\t\tnewNodeData.credentials = undefined;\n\t// \t\t\t\t\tbreak;\n\t// \t\t\t\t}\n\t// \t\t\t\tconst optionValue = authDisplayOptions[displayOption]?.[0];\n\t// \t\t\t\tif (optionValue && typeof optionValue === 'string') {\n\t// \t\t\t\t\tparameters[displayOption] = optionValue;\n\t// \t\t\t\t}\n\t// \t\t\t\tnewNodeData.parameters = {\n\t// \t\t\t\t\t...newNodeData.parameters,\n\t// \t\t\t\t\t...parameters,\n\t// \t\t\t\t};\n\t// \t\t\t}\n\t// \t\t}\n\t// \t}\n\t// }\n\n\treturn newNodeData;\n}\n\n/**\n * @TODO Implement if needed\n */\n// async loadNodesProperties(nodeInfos: INodeTypeNameVersion[]): Promise<void> {\n// \tconst allNodes: INodeTypeDescription[] = this.nodeTypesStore.allNodeTypes;\n//\n// const nodesToBeFetched: INodeTypeNameVersion[] = [];\n// allNodes.forEach((node) => {\n// \tconst nodeVersions = Array.isArray(node.version) ? node.version : [node.version];\n// \tif (\n// \t\t!!nodeInfos.find((n) => n.name === node.name && nodeVersions.includes(n.version)) &&\n// \t\t!node.hasOwnProperty('properties')\n// \t) {\n// \t\tnodesToBeFetched.push({\n// \t\t\tname: node.name,\n// \t\t\tversion: Array.isArray(node.version) ? node.version.slice(-1)[0] : node.version,\n// \t\t});\n// \t}\n// });\n//\n// if (nodesToBeFetched.length > 0) {\n// \t// Only call API if node information is actually missing\n// \tthis.canvasStore.startLoading();\n// \tawait this.nodeTypesStore.getNodesInformation(nodesToBeFetched);\n// \tthis.canvasStore.stopLoading();\n// }\n// }\n\n/**\n * @TODO Probably not needed and can be merged into addNode\n */\nasync function injectNode(\n\tnodeTypeName: string,\n\toptions: AddNodeOptions = {},\n\tshowDetail = true,\n\ttrackHistory = false,\n\tisAutoAdd = false,\n) {\n\t// const nodeTypeData: INodeTypeDescription | null =\n\t// \tthis.nodeTypesStore.getNodeType(nodeTypeName);\n\t//\n\t// if (nodeTypeData === null) {\n\t// \tthis.showMessage({\n\t// \t\ttitle: this.$locale.baseText('nodeView.showMessage.addNodeButton.title'),\n\t// \t\tmessage: this.$locale.baseText('nodeView.showMessage.addNodeButton.message', {\n\t// \t\t\tinterpolate: { nodeTypeName },\n\t// \t\t}),\n\t// \t\ttype: 'error',\n\t// \t});\n\t// \treturn;\n\t// }\n\t//\n\t// if (\n\t// \tnodeTypeData.maxNodes !== undefined &&\n\t// \tthis.workflowHelpers.getNodeTypeCount(nodeTypeName) >= nodeTypeData.maxNodes\n\t// ) {\n\t// \tthis.showMaxNodeTypeError(nodeTypeData);\n\t// \treturn;\n\t// }\n\t//\n\t// const newNodeData = await this.getNewNodeWithDefaultCredential(nodeTypeData, {\n\t// \tname: options.name,\n\t// });\n\t//\n\t// // when pulling new connection from node or injecting into a connection\n\t// const lastSelectedNode = this.lastSelectedNode;\n\t//\n\t// if (options.position) {\n\t// \tnewNodeData.position = NodeViewUtils.getNewNodePosition(\n\t// \t\tthis.canvasStore.getNodesWithPlaceholderNode(),\n\t// \t\toptions.position,\n\t// \t);\n\t// } else if (lastSelectedNode) {\n\t// \tconst lastSelectedConnection = this.canvasStore.lastSelectedConnection;\n\t// \tif (lastSelectedConnection) {\n\t// \t\t// set when injecting into a connection\n\t// \t\tconst [diffX] = NodeViewUtils.getConnectorLengths(lastSelectedConnection);\n\t// \t\tif (diffX <= NodeViewUtils.MAX_X_TO_PUSH_DOWNSTREAM_NODES) {\n\t// \t\t\tthis.pushDownstreamNodes(\n\t// \t\t\t\tlastSelectedNode.name,\n\t// \t\t\t\tNodeViewUtils.PUSH_NODES_OFFSET,\n\t// \t\t\t\ttrackHistory,\n\t// \t\t\t);\n\t// \t\t}\n\t// \t}\n\t//\n\t// \t// set when pulling connections\n\t// \tif (this.canvasStore.newNodeInsertPosition) {\n\t// \t\tnewNodeData.position = NodeViewUtils.getNewNodePosition(this.nodes, [\n\t// \t\t\tthis.canvasStore.newNodeInsertPosition[0] + NodeViewUtils.GRID_SIZE,\n\t// \t\t\tthis.canvasStore.newNodeInsertPosition[1] - NodeViewUtils.NODE_SIZE / 2,\n\t// \t\t]);\n\t// \t\tthis.canvasStore.newNodeInsertPosition = null;\n\t// \t} else {\n\t// \t\tlet yOffset = 0;\n\t// \t\tconst workflow = this.workflowHelpers.getCurrentWorkflow();\n\t//\n\t// \t\tif (lastSelectedConnection) {\n\t// \t\t\tconst sourceNodeType = this.nodeTypesStore.getNodeType(\n\t// \t\t\t\tlastSelectedNode.type,\n\t// \t\t\t\tlastSelectedNode.typeVersion,\n\t// \t\t\t);\n\t//\n\t// \t\t\tif (sourceNodeType) {\n\t// \t\t\t\tconst offsets = [\n\t// \t\t\t\t\t[-100, 100],\n\t// \t\t\t\t\t[-140, 0, 140],\n\t// \t\t\t\t\t[-240, -100, 100, 240],\n\t// \t\t\t\t];\n\t//\n\t// \t\t\t\tconst sourceNodeOutputs = NodeHelpers.getNodeOutputs(\n\t// \t\t\t\t\tworkflow,\n\t// \t\t\t\t\tlastSelectedNode,\n\t// \t\t\t\t\tsourceNodeType,\n\t// \t\t\t\t);\n\t// \t\t\t\tconst sourceNodeOutputTypes = NodeHelpers.getConnectionTypes(sourceNodeOutputs);\n\t//\n\t// \t\t\t\tconst sourceNodeOutputMainOutputs = sourceNodeOutputTypes.filter(\n\t// \t\t\t\t\t(output) => output === NodeConnectionType.Main,\n\t// \t\t\t\t);\n\t//\n\t// \t\t\t\tif (sourceNodeOutputMainOutputs.length > 1) {\n\t// \t\t\t\t\tconst offset = offsets[sourceNodeOutputMainOutputs.length - 2];\n\t// \t\t\t\t\tconst sourceOutputIndex = lastSelectedConnection.__meta\n\t// \t\t\t\t\t\t? lastSelectedConnection.__meta.sourceOutputIndex\n\t// \t\t\t\t\t\t: 0;\n\t// \t\t\t\t\tyOffset = offset[sourceOutputIndex];\n\t// \t\t\t\t}\n\t// \t\t\t}\n\t// \t\t}\n\t//\n\t// \t\tlet outputs: Array<ConnectionTypes | INodeOutputConfiguration> = [];\n\t// \t\ttry {\n\t// \t\t\t// It fails when the outputs are an expression. As those nodes have\n\t// \t\t\t// normally no outputs by default and the only reason we need the\n\t// \t\t\t// outputs here is to calculate the position, it is fine to assume\n\t// \t\t\t// that they have no outputs and are so treated as a regular node\n\t// \t\t\t// with only \"main\" outputs.\n\t// \t\t\toutputs = NodeHelpers.getNodeOutputs(workflow, newNodeData, nodeTypeData);\n\t// \t\t} catch (e) {}\n\t// \t\tconst outputTypes = NodeHelpers.getConnectionTypes(outputs);\n\t// \t\tconst lastSelectedNodeType = this.nodeTypesStore.getNodeType(\n\t// \t\t\tlastSelectedNode.type,\n\t// \t\t\tlastSelectedNode.typeVersion,\n\t// \t\t);\n\t//\n\t// \t\t// If node has only scoped outputs, position it below the last selected node\n\t// \t\tif (\n\t// \t\t\toutputTypes.length > 0 &&\n\t// \t\t\toutputTypes.every((outputName) => outputName !== NodeConnectionType.Main)\n\t// \t\t) {\n\t// \t\t\tconst lastSelectedNodeWorkflow = workflow.getNode(lastSelectedNode.name);\n\t// \t\t\tconst lastSelectedInputs = NodeHelpers.getNodeInputs(\n\t// \t\t\t\tworkflow,\n\t// \t\t\t\tlastSelectedNodeWorkflow,\n\t// \t\t\t\tlastSelectedNodeType,\n\t// \t\t\t);\n\t// \t\t\tconst lastSelectedInputTypes = NodeHelpers.getConnectionTypes(lastSelectedInputs);\n\t//\n\t// \t\t\tconst scopedConnectionIndex = (lastSelectedInputTypes || [])\n\t// \t\t\t\t.filter((input) => input !== NodeConnectionType.Main)\n\t// \t\t\t\t.findIndex((inputType) => outputs[0] === inputType);\n\t//\n\t// \t\t\tnewNodeData.position = NodeViewUtils.getNewNodePosition(\n\t// \t\t\t\tthis.nodes,\n\t// \t\t\t\t[\n\t// \t\t\t\t\tlastSelectedNode.position[0] +\n\t// \t\t\t\t\t(NodeViewUtils.NODE_SIZE /\n\t// \t\t\t\t\t\t(Math.max(lastSelectedNodeType?.inputs?.length ?? 1), 1)) *\n\t// \t\t\t\t\tscopedConnectionIndex,\n\t// \t\t\t\t\tlastSelectedNode.position[1] + NodeViewUtils.PUSH_NODES_OFFSET,\n\t// \t\t\t\t],\n\t// \t\t\t\t[100, 0],\n\t// \t\t\t);\n\t// \t\t} else {\n\t// \t\t\t// Has only main outputs or no outputs at all\n\t// \t\t\tconst inputs = NodeHelpers.getNodeInputs(\n\t// \t\t\t\tworkflow,\n\t// \t\t\t\tlastSelectedNode,\n\t// \t\t\t\tlastSelectedNodeType,\n\t// \t\t\t);\n\t// \t\t\tconst inputsTypes = NodeHelpers.getConnectionTypes(inputs);\n\t//\n\t// \t\t\tlet pushOffset = NodeViewUtils.PUSH_NODES_OFFSET;\n\t// \t\t\tif (!!inputsTypes.find((input) => input !== NodeConnectionType.Main)) {\n\t// \t\t\t\t// If the node has scoped inputs, push it down a bit more\n\t// \t\t\t\tpushOffset += 150;\n\t// \t\t\t}\n\t//\n\t// \t\t\t// If a node is active then add the new node directly after the current one\n\t// \t\t\tnewNodeData.position = NodeViewUtils.getNewNodePosition(\n\t// \t\t\t\tthis.nodes,\n\t// \t\t\t\t[lastSelectedNode.position[0] + pushOffset, lastSelectedNode.position[1] + yOffset],\n\t// \t\t\t\t[100, 0],\n\t// \t\t\t);\n\t// \t\t}\n\t// \t}\n\t// } else {\n\t// \t// If added node is a trigger and it's the first one added to the canvas\n\t// \t// we place it at canvasAddButtonPosition to replace the canvas add button\n\t// \tconst position =\n\t// \t\tthis.nodeTypesStore.isTriggerNode(nodeTypeName) && !this.containsTrigger\n\t// \t\t\t? this.canvasStore.canvasAddButtonPosition\n\t// \t\t\t: // If no node is active find a free spot\n\t// \t\t\t(this.lastClickPosition as XYPosition);\n\t//\n\t// \tnewNodeData.position = NodeViewUtils.getNewNodePosition(this.nodes, position);\n\t// }\n\t//\n\t// const localizedName = this.locale.localizeNodeName(newNodeData.name, newNodeData.type);\n\t//\n\t// newNodeData.name = this.uniqueNodeName(localizedName);\n\t//\n\t// if (nodeTypeData.webhooks?.length) {\n\t// \tnewNodeData.webhookId = uuid();\n\t// }\n\t//\n\t// await this.addNodes([newNodeData], undefined, trackHistory);\n\t// this.workflowsStore.setNodePristine(newNodeData.name, true);\n\t//\n\t// this.uiStore.stateIsDirty = true;\n\t//\n\t// if (nodeTypeName === STICKY_NODE_TYPE) {\n\t// \tthis.$telemetry.trackNodesPanel('nodeView.addSticky', {\n\t// \t\tworkflow_id: this.workflowsStore.workflowId,\n\t// \t});\n\t// } else {\n\t// \tvoid this.externalHooks.run('nodeView.addNodeButton', { nodeTypeName });\n\t// \tuseSegment().trackAddedTrigger(nodeTypeName);\n\t// \tconst trackProperties: ITelemetryTrackProperties = {\n\t// \t\tnode_type: nodeTypeName,\n\t// \t\tnode_version: newNodeData.typeVersion,\n\t// \t\tis_auto_add: isAutoAdd,\n\t// \t\tworkflow_id: this.workflowsStore.workflowId,\n\t// \t\tdrag_and_drop: options.dragAndDrop,\n\t// \t};\n\t//\n\t// \tif (lastSelectedNode) {\n\t// \t\ttrackProperties.input_node_type = lastSelectedNode.type;\n\t// \t}\n\t//\n\t// \tthis.$telemetry.trackNodesPanel('nodeView.addNodeButton', trackProperties);\n\t// }\n\t//\n\t// // Automatically deselect all nodes and select the current one and also active\n\t// // current node. But only if it's added manually by the user (not by undo/redo mechanism)\n\t// if (trackHistory) {\n\t// \tthis.deselectAllNodes();\n\t// \tsetTimeout(() => {\n\t// \t\tthis.nodeSelectedByName(\n\t// \t\t\tnewNodeData.name,\n\t// \t\t\tshowDetail && nodeTypeName !== STICKY_NODE_TYPE,\n\t// \t\t);\n\t// \t});\n\t// }\n\t//\n\t// return newNodeData;\n}\n\nfunction checkIfEditingIsAllowed(): boolean {\n\tif (readOnlyNotification.value?.visible) {\n\t\treturn false;\n\t}\n\n\tif (isReadOnlyRoute.value || isReadOnlyEnvironment.value) {\n\t\tconst messageContext = isReadOnlyRoute.value ? 'executions' : 'workflows';\n\t\treadOnlyNotification.value = toast.showMessage({\n\t\t\ttitle: i18n.baseText(\n\t\t\t\tisReadOnlyEnvironment.value\n\t\t\t\t\t? `readOnlyEnv.showMessage.${messageContext}.title`\n\t\t\t\t\t: 'readOnly.showMessage.executions.title',\n\t\t\t),\n\t\t\tmessage: i18n.baseText(\n\t\t\t\tisReadOnlyEnvironment.value\n\t\t\t\t\t? `readOnlyEnv.showMessage.${messageContext}.message`\n\t\t\t\t\t: 'readOnly.showMessage.executions.message',\n\t\t\t),\n\t\t\ttype: 'info',\n\t\t\tdangerouslyUseHTMLString: true,\n\t\t}) as unknown as { visible: boolean };\n\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n</script>\n\n<template>\n\t<WorkflowCanvas\n\t\tv-if=\"editableWorkflow && editableWorkflowObject\"\n\t\t:workflow=\"editableWorkflow\"\n\t\t:workflow-object=\"editableWorkflowObject\"\n\t\t@update:node:position=\"onNodePositionUpdate\"\n\t\t@create:connection=\"onCreateNodeConnection\"\n\t>\n\t\t<div :class=\"$style.executionButtons\">\n\t\t\t<CanvasExecuteWorkflowButton @click=\"onRunWorkflow\" />\n\t\t</div>\n\t\t<Suspense>\n\t\t\t<NodeCreation\n\t\t\t\tv-if=\"!isReadOnlyRoute && !isReadOnlyEnvironment\"\n\t\t\t\t:create-node-active=\"uiStore.isCreateNodeActive\"\n\t\t\t\t:node-view-scale=\"1\"\n\t\t\t\t@toggle-node-creator=\"onToggleNodeCreator\"\n\t\t\t\t@add-nodes=\"onAddNodes\"\n\t\t\t/>\n\t\t</Suspense>\n\t</WorkflowCanvas>\n</template>\n\n<style lang=\"scss\" module>\n.executionButtons {\n\tposition: absolute;\n\tdisplay: flex;\n\tjustify-content: center;\n\talign-items: center;\n\tleft: 50%;\n\ttransform: translateX(-50%);\n\tbottom: var(--spacing-l);\n\twidth: auto;\n\n\t@media (max-width: $breakpoint-2xs) {\n\t\tbottom: 150px;\n\t}\n\n\tbutton {\n\t\tdisplay: flex;\n\t\tjustify-content: center;\n\t\talign-items: center;\n\t\tmargin-left: 0.625rem;\n\n\t\t&:first-child {\n\t\t\tmargin: 0;\n\t\t}\n\t}\n}\n</style>\n"],"file":"assets/NodeView.v2-Oz2vwdfG.js"}
1
+ {"version":3,"mappings":"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","names":["workflowRunning","nodeDisabledTitle","node","inject","CanvasNodeKey","data","computed","$style","useCssModule","executeNode","toggleDisableNode","deleteNode","openContextMenu","e","type","useNodeConnections","inputs","outputs","mainInputs","unref","input","NodeConnectionType","nonMainInputs","requiredNonMainInputs","mainOutputs","output","nonMainOutputs","label","classes","styles","stylesObject","spacerCount","slots","_useSlots","Render","Component","CanvasNodeConfigurable","CanvasNodeConfiguration","CanvasNodeDefault","h","handle","CanvasNodeHandleKey","props","__props","handleType","isConnectableStart","isConnectableEnd","renderProps","CanvasHandleMainInput","CanvasHandleMainOutput","CanvasHandleNonMain","toRef","provide","nodeTypesStore","useNodeTypesStore","nodeType","inputsWithPosition","mapEndpointWithPosition","Position","outputsWithPosition","position","offsetAxis","endpoint","index","endpoints","id","selected","edgeStyle","path","getBezierPath","emit","__emit","onNodeDragStop","onConnect","args","mapLegacyConnectionsToCanvasConnections","legacyConnections","nodes","mappedConnections","fromNodeName","fromId","_a","fromConnectionType","toPorts","fromIndex","toPort","toId","toConnectionType","toIndex","mapLegacyEndpointsToCanvasConnectionPort","endpointIndex","required","getUniqueNodeName","name","existingNames","i","newName","uuid","useCanvasMapping","workflow","workflowObject","locale","useI18n","renderTypeByNodeType","acc","renderType","nodeInputsById","nodeTypeDescription","workflowObjectNode","NodeHelpers.getNodeInputs","nodeOutputsById","NodeHelpers.getNodeOutputs","elements","connections","connection","getConnectionType","getConnectionLabel","_","pinData","_b","uiStore","useUIStore","runButtonText","NodeCreation","defineAsyncComponent","__vitePreload","n","router","useRouter","route","useRoute","i18n","telemetry","useTelemetry","externalHooks","useExternalHooks","toast","useToast","workflowsStore","useWorkflowsStore","useWorkflowsEEStore","tagsStore","useTagsStore","sourceControlStore","useSourceControlStore","nodeCreatorStore","useNodeCreatorStore","settingsStore","useSettingsStore","credentialsStore","useCredentialsStore","environmentsStore","useEnvironmentsStore","externalSecretsStore","useExternalSecretsStore","rootStore","useRootStore","collaborationStore","useCollaborationStore","runWorkflow","useRunWorkflow","isLoading","ref","readOnlyNotification","workflowId","editableWorkflow","editableWorkflowObject","isDemoRoute","VIEWS","isReadOnlyRoute","isReadOnlyEnvironment","triggerNodes","onMounted","initialize","loadPromises","EnterpriseEditionFeature","error","initializeEditableWorkflow","targetWorkflow","tags","tagIds","tag","onRunWorkflow","onNodePositionUpdate","onCreateNodeConnection","sourceNodeId","sourceNode","sourceNodeName","sourceType","sourceIndex","targetNodeId","targetNode","targetNodeName","targetType","targetIndex","checkIfNodeConnectionIsAllowed","onToggleNodeCreator","source","createNodeActive","nodeCreatorView","REGULAR_NODE_CREATOR_VIEW","TRIGGER_NODE_CREATOR_VIEW","mode","AI_NODE_CREATOR_VIEW","onAddNodes","dragAndDrop","currentPosition","nodePosition","isAutoAdd","openDetail","addNode","lastAddedNode","NodeViewUtils.NODE_SIZE","NodeViewUtils.GRID_SIZE","newNodesOffset","from","to","fromNode","toNode","options","checkIfEditingIsAllowed","newNodeData","createNodeWithDefaultCredentials","nodeVersion","messageContext"],"ignoreList":[],"sources":["../../src/components/canvas/elements/nodes/CanvasNodeToolbar.vue","../../src/composables/useNodeConnections.ts","../../src/components/canvas/elements/nodes/render-types/CanvasNodeDefault.vue","../../src/components/canvas/elements/nodes/render-types/CanvasNodeConfiguration.vue","../../src/components/canvas/elements/nodes/render-types/CanvasNodeConfigurable.vue","../../src/components/canvas/elements/nodes/CanvasNodeRenderer.vue","../../src/components/canvas/elements/handles/render-types/CanvasHandleMainInput.vue","../../src/components/canvas/elements/handles/render-types/CanvasHandleMainOutput.vue","../../src/components/canvas/elements/handles/render-types/CanvasHandleNonMain.vue","../../src/components/canvas/elements/handles/HandleRenderer.vue","../../src/components/canvas/elements/nodes/CanvasNode.vue","../../src/components/canvas/elements/edges/CanvasEdge.vue","../../src/components/canvas/Canvas.vue","../../src/utils/canvasUtilsV2.ts","../../src/composables/useCanvasMapping.ts","../../src/components/canvas/WorkflowCanvas.vue","../../src/components/canvas/elements/buttons/CanvasExecuteWorkflowButton.vue","../../src/views/NodeView.v2.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, inject, useCssModule } from 'vue';\nimport { CanvasNodeKey } from '@/constants';\n\nconst node = inject(CanvasNodeKey);\n\nconst data = computed(() => node?.data.value);\n\nconst $style = useCssModule();\n\n// @TODO\nconst workflowRunning = false;\n\n// @TODO\nconst nodeDisabledTitle = 'Test';\n\n// @TODO\nfunction executeNode() {}\n\n// @TODO\nfunction toggleDisableNode() {}\n\n// @TODO\nfunction deleteNode() {}\n\n// @TODO\nfunction openContextMenu(e: MouseEvent, type: string) {}\n</script>\n\n<template>\n\t<div :class=\"$style.canvasNodeToolbar\">\n\t\t<div :class=\"$style.canvasNodeToolbarItems\">\n\t\t\t<N8nIconButton\n\t\t\t\tv-if=\"data?.renderType !== 'configuration'\"\n\t\t\t\tdata-test-id=\"execute-node-button\"\n\t\t\t\ttype=\"tertiary\"\n\t\t\t\ttext\n\t\t\t\tsize=\"small\"\n\t\t\t\ticon=\"play\"\n\t\t\t\t:disabled=\"workflowRunning\"\n\t\t\t\t:title=\"$locale.baseText('node.testStep')\"\n\t\t\t\t@click=\"executeNode\"\n\t\t\t/>\n\t\t\t<N8nIconButton\n\t\t\t\tdata-test-id=\"disable-node-button\"\n\t\t\t\ttype=\"tertiary\"\n\t\t\t\ttext\n\t\t\t\tsize=\"small\"\n\t\t\t\ticon=\"power-off\"\n\t\t\t\t:title=\"nodeDisabledTitle\"\n\t\t\t\t@click=\"toggleDisableNode\"\n\t\t\t/>\n\t\t\t<N8nIconButton\n\t\t\t\tdata-test-id=\"delete-node-button\"\n\t\t\t\ttype=\"tertiary\"\n\t\t\t\tsize=\"small\"\n\t\t\t\ttext\n\t\t\t\ticon=\"trash\"\n\t\t\t\t:title=\"$locale.baseText('node.delete')\"\n\t\t\t\t@click=\"deleteNode\"\n\t\t\t/>\n\t\t\t<N8nIconButton\n\t\t\t\tdata-test-id=\"overflow-node-button\"\n\t\t\t\ttype=\"tertiary\"\n\t\t\t\tsize=\"small\"\n\t\t\t\ttext\n\t\t\t\ticon=\"ellipsis-h\"\n\t\t\t\t@click=\"(e: MouseEvent) => openContextMenu(e, 'node-button')\"\n\t\t\t/>\n\t\t</div>\n\t</div>\n</template>\n\n<style lang=\"scss\" module>\n.canvasNodeToolbar {\n\tpadding-bottom: var(--spacing-3xs);\n}\n\n.canvasNodeToolbarItems {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n}\n</style>\n","import type { CanvasElementData } from '@/types';\nimport type { MaybeRef } from 'vue';\nimport { computed, unref } from 'vue';\nimport { NodeConnectionType } from 'n8n-workflow';\n\nexport function useNodeConnections({\n\tinputs,\n\toutputs,\n}: {\n\tinputs: MaybeRef<CanvasElementData['inputs']>;\n\toutputs: MaybeRef<CanvasElementData['outputs']>;\n}) {\n\t/**\n\t * Inputs\n\t */\n\n\tconst mainInputs = computed(() =>\n\t\tunref(inputs).filter((input) => input.type === NodeConnectionType.Main),\n\t);\n\n\tconst nonMainInputs = computed(() =>\n\t\tunref(inputs).filter((input) => input.type !== NodeConnectionType.Main),\n\t);\n\n\tconst requiredNonMainInputs = computed(() =>\n\t\tnonMainInputs.value.filter((input) => input.required),\n\t);\n\n\t/**\n\t * Outputs\n\t */\n\n\tconst mainOutputs = computed(() =>\n\t\tunref(outputs).filter((output) => output.type === NodeConnectionType.Main),\n\t);\n\tconst nonMainOutputs = computed(() =>\n\t\tunref(outputs).filter((output) => output.type !== NodeConnectionType.Main),\n\t);\n\n\treturn {\n\t\tmainInputs,\n\t\tnonMainInputs,\n\t\trequiredNonMainInputs,\n\t\tmainOutputs,\n\t\tnonMainOutputs,\n\t};\n}\n","<script lang=\"ts\" setup>\nimport { computed, inject, useCssModule } from 'vue';\nimport { useNodeConnections } from '@/composables/useNodeConnections';\nimport { CanvasNodeKey } from '@/constants';\n\nconst node = inject(CanvasNodeKey);\n\nconst $style = useCssModule();\n\nconst label = computed(() => node?.label.value ?? '');\nconst inputs = computed(() => node?.data.value.inputs ?? []);\nconst outputs = computed(() => node?.data.value.outputs ?? []);\n\nconst { mainOutputs } = useNodeConnections({\n\tinputs,\n\toutputs,\n});\n\nconst classes = computed(() => {\n\treturn {\n\t\t[$style.node]: true,\n\t\t[$style.selected]: node?.selected.value,\n\t};\n});\n\nconst styles = computed(() => {\n\treturn {\n\t\t'--node-main-output-count': mainOutputs.value.length,\n\t};\n});\n</script>\n\n<template>\n\t<div v-if=\"node\" :class=\"classes\" :style=\"styles\" data-test-id=\"canvas-node-default\">\n\t\t<slot />\n\t\t<div v-if=\"label\" :class=\"$style.label\">{{ label }}</div>\n\t</div>\n</template>\n\n<style lang=\"scss\" module>\n.node {\n\theight: calc(100px + max(0, var(--node-main-output-count, 1) - 4) * 50px);\n\twidth: 100px;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tbackground: var(--canvas-node--background, var(--color-canvas-node-background));\n\tborder: 2px solid var(--canvas-node--border-color, var(--color-foreground-xdark));\n\tborder-radius: var(--border-radius-large);\n}\n\n.label {\n\ttop: 100%;\n\tposition: absolute;\n\tfont-size: var(--font-size-m);\n\ttext-align: center;\n\twidth: 100%;\n\tmin-width: 200px;\n\tmargin-top: var(--spacing-2xs);\n}\n\n.selected {\n\tbox-shadow: 0 0 0 4px var(--color-canvas-selected);\n}\n</style>\n","<script lang=\"ts\" setup>\nimport { computed, inject, useCssModule } from 'vue';\nimport { CanvasNodeKey } from '@/constants';\n\nconst node = inject(CanvasNodeKey);\n\nconst $style = useCssModule();\n\nconst label = computed(() => node?.label.value ?? '');\n\nconst classes = computed(() => {\n\treturn {\n\t\t[$style.node]: true,\n\t\t[$style.selected]: node?.selected.value,\n\t};\n});\n</script>\n\n<template>\n\t<div :class=\"classes\" data-test-id=\"canvas-node-configuration\">\n\t\t<slot />\n\t\t<div v-if=\"label\" :class=\"$style.label\">{{ label }}</div>\n\t</div>\n</template>\n\n<style lang=\"scss\" module>\n.node {\n\twidth: 75px;\n\theight: 75px;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tbackground: var(--canvas-node--background, var(--node-type-supplemental-background));\n\tborder: 2px solid var(--canvas-node--border-color, var(--color-foreground-dark));\n\tborder-radius: 50%;\n}\n\n.selected {\n\tbox-shadow: 0 0 0 4px var(--color-canvas-selected);\n}\n\n.label {\n\ttop: 100%;\n\tposition: absolute;\n\tfont-size: var(--font-size-m);\n\ttext-align: center;\n\twidth: 100%;\n\tmin-width: 200px;\n\tmargin-top: var(--spacing-2xs);\n}\n</style>\n","<script lang=\"ts\" setup>\nimport { computed, inject, useCssModule } from 'vue';\nimport { CanvasNodeKey, NODE_INSERT_SPACER_BETWEEN_INPUT_GROUPS } from '@/constants';\nimport { useNodeConnections } from '@/composables/useNodeConnections';\n\nconst node = inject(CanvasNodeKey);\n\nconst $style = useCssModule();\n\nconst label = computed(() => node?.label.value ?? '');\nconst inputs = computed(() => node?.data.value.inputs ?? []);\nconst outputs = computed(() => node?.data.value.outputs ?? []);\n\nconst { nonMainInputs, requiredNonMainInputs } = useNodeConnections({\n\tinputs,\n\toutputs,\n});\n\nconst classes = computed(() => {\n\treturn {\n\t\t[$style.node]: true,\n\t\t[$style.selected]: node?.selected.value,\n\t};\n});\n\nconst styles = computed(() => {\n\tconst stylesObject: {\n\t\t[key: string]: string | number;\n\t} = {};\n\n\tif (requiredNonMainInputs.value.length > 0) {\n\t\tlet spacerCount = 0;\n\t\tif (NODE_INSERT_SPACER_BETWEEN_INPUT_GROUPS) {\n\t\t\tconst requiredNonMainInputsCount = requiredNonMainInputs.value.length;\n\t\t\tconst optionalNonMainInputsCount = nonMainInputs.value.length - requiredNonMainInputsCount;\n\t\t\tspacerCount = requiredNonMainInputsCount > 0 && optionalNonMainInputsCount > 0 ? 1 : 0;\n\t\t}\n\n\t\tstylesObject['--configurable-node-input-count'] = nonMainInputs.value.length + spacerCount;\n\t}\n\n\treturn stylesObject;\n});\n</script>\n\n<template>\n\t<div :class=\"classes\" :style=\"styles\" data-test-id=\"canvas-node-configurable\">\n\t\t<slot />\n\t\t<div :class=\"$style.label\">{{ label }}</div>\n\t</div>\n</template>\n\n<style lang=\"scss\" module>\n.node {\n\t--configurable-node-min-input-count: 4;\n\t--configurable-node-input-width: 65px;\n\n\twidth: calc(\n\t\tmax(var(--configurable-node-input-count, 5), var(--configurable-node-min-input-count)) *\n\t\t\tvar(--configurable-node-input-width)\n\t);\n\theight: 100px;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tbackground: var(--canvas-node--background, var(--color-canvas-node-background));\n\tborder: 2px solid var(--canvas-node--border-color, var(--color-foreground-xdark));\n\tborder-radius: var(--border-radius-large);\n}\n\n.label {\n\ttop: 100%;\n\tfont-size: var(--font-size-m);\n\ttext-align: center;\n\tmargin-left: var(--spacing-s);\n\tmax-width: calc(\n\t\tvar(--node-width) - var(--configurable-node-icon-offset) - var(--configurable-node-icon-size) -\n\t\t\t2 * var(--spacing-s)\n\t);\n}\n\n.selected {\n\tbox-shadow: 0 0 0 4px var(--color-canvas-selected);\n}\n</style>\n","<script lang=\"ts\" setup>\nimport { h, inject } from 'vue';\nimport CanvasNodeDefault from '@/components/canvas/elements/nodes/render-types/CanvasNodeDefault.vue';\nimport CanvasNodeConfiguration from '@/components/canvas/elements/nodes/render-types/CanvasNodeConfiguration.vue';\nimport CanvasNodeConfigurable from '@/components/canvas/elements/nodes/render-types/CanvasNodeConfigurable.vue';\nimport { CanvasNodeKey } from '@/constants';\n\nconst node = inject(CanvasNodeKey);\n\nconst slots = defineSlots<{\n\tdefault?: () => unknown;\n}>();\n\nconst Render = () => {\n\tlet Component;\n\tswitch (node?.data.value.renderType) {\n\t\tcase 'configurable':\n\t\t\tComponent = CanvasNodeConfigurable;\n\t\t\tbreak;\n\n\t\tcase 'configuration':\n\t\t\tComponent = CanvasNodeConfiguration;\n\t\t\tbreak;\n\n\t\tcase 'trigger':\n\t\t\tComponent = CanvasNodeDefault;\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tComponent = CanvasNodeDefault;\n\t}\n\n\treturn h(Component, slots.default);\n};\n</script>\n\n<template>\n\t<Render />\n</template>\n","<script lang=\"ts\" setup>\nimport { computed, inject, useCssModule } from 'vue';\nimport { CanvasNodeHandleKey } from '@/constants';\n\nconst handle = inject(CanvasNodeHandleKey);\n\nconst $style = useCssModule();\n\nconst label = computed(() => handle?.label.value ?? '');\n</script>\n<template>\n\t<div :class=\"['canvas-node-handle-main-input', $style.handle]\">\n\t\t<div :class=\"$style.label\">{{ label }}</div>\n\t</div>\n</template>\n\n<style lang=\"scss\" module>\n.handle {\n\twidth: 8px;\n\theight: 16px;\n\tborder-radius: 0;\n\tbackground: var(--color-foreground-xdark);\n\n\t&:hover {\n\t\tbackground: var(--color-primary);\n\t}\n}\n\n.label {\n\tposition: absolute;\n\ttop: 50%;\n\tright: 12px;\n\ttransform: translate(0, -50%);\n\tfont-size: var(--font-size-2xs);\n\tcolor: var(--color-foreground-xdark);\n\tbackground: var(--color-background-light);\n\tz-index: 1;\n}\n</style>\n","<script lang=\"ts\" setup>\nimport { computed, inject, useCssModule } from 'vue';\nimport { CanvasNodeHandleKey } from '@/constants';\n\nconst handle = inject(CanvasNodeHandleKey);\n\n// const group = svg.node('g');\n// const containerBorder = svg.node('rect', {\n// \trx: 3,\n// \t'stroke-width': 2,\n// \tfillOpacity: 0,\n// \theight: ep.params.dimensions - 2,\n// \twidth: ep.params.dimensions - 2,\n// \ty: 1,\n// \tx: 1,\n// });\n// const plusPath = svg.node('path', {\n// \td: 'm16.40655,10.89837l-3.30491,0l0,-3.30491c0,-0.40555 -0.32889,-0.73443 -0.73443,-0.73443l-0.73443,0c-0.40554,0 -0.73442,0.32888 -0.73442,0.73443l0,3.30491l-3.30491,0c-0.40555,0 -0.73443,0.32888 -0.73443,0.73442l0,0.73443c0,0.40554 0.32888,0.73443 0.73443,0.73443l3.30491,0l0,3.30491c0,0.40554 0.32888,0.73442 0.73442,0.73442l0.73443,0c0.40554,0 0.73443,-0.32888 0.73443,-0.73442l0,-3.30491l3.30491,0c0.40554,0 0.73442,-0.32889 0.73442,-0.73443l0,-0.73443c0,-0.40554 -0.32888,-0.73442 -0.73442,-0.73442z',\n// });\n// if (ep.params.size !== 'medium') {\n// \tep.addClass(ep.params.size);\n// }\n// group.appendChild(containerBorder);\n// group.appendChild(plusPath);\n//\n// ep.setupOverlays();\n// ep.setVisible(false);\n// return group;\n\nconst $style = useCssModule();\n\nconst label = computed(() => handle?.label.value ?? '');\n</script>\n<template>\n\t<div :class=\"['canvas-node-handle-main-output', $style.handle]\">\n\t\t<div :class=\"$style.label\">{{ label }}</div>\n\t\t<div :class=\"$style.circle\" />\n\t\t<!-- @TODO Determine whether handle is connected and find a way to make it work without pointer-events: none -->\n\t\t<!--\t\t<svg :class=\"$style.plus\" viewBox=\"0 0 70 24\">-->\n\t\t<!--\t\t\t<line x1=\"0\" y1=\"12\" x2=\"46\" y2=\"12\" stroke=\"var(&#45;&#45;color-foreground-xdark)\" />-->\n\t\t<!--\t\t\t<rect-->\n\t\t<!--\t\t\t\tx=\"46\"-->\n\t\t<!--\t\t\t\ty=\"2\"-->\n\t\t<!--\t\t\t\twidth=\"20\"-->\n\t\t<!--\t\t\t\theight=\"20\"-->\n\t\t<!--\t\t\t\tstroke=\"var(&#45;&#45;color-foreground-xdark)\"-->\n\t\t<!--\t\t\t\tstroke-width=\"2\"-->\n\t\t<!--\t\t\t\trx=\"4\"-->\n\t\t<!--\t\t\t\tfill=\"#ffffff\"-->\n\t\t<!--\t\t\t/>-->\n\t\t<!--\t\t\t<g transform=\"translate(44, 0)\">-->\n\t\t<!--\t\t\t\t<path-->\n\t\t<!--\t\t\t\t\tfill=\"var(&#45;&#45;color-foreground-xdark)\"-->\n\t\t<!--\t\t\t\t\td=\"m16.40655,10.89837l-3.30491,0l0,-3.30491c0,-0.40555 -0.32889,-0.73443 -0.73443,-0.73443l-0.73443,0c-0.40554,0 -0.73442,0.32888 -0.73442,0.73443l0,3.30491l-3.30491,0c-0.40555,0 -0.73443,0.32888 -0.73443,0.73442l0,0.73443c0,0.40554 0.32888,0.73443 0.73443,0.73443l3.30491,0l0,3.30491c0,0.40554 0.32888,0.73442 0.73442,0.73442l0.73443,0c0.40554,0 0.73443,-0.32888 0.73443,-0.73442l0,-3.30491l3.30491,0c0.40554,0 0.73442,-0.32889 0.73442,-0.73443l0,-0.73443c0,-0.40554 -0.32888,-0.73442 -0.73442,-0.73442z\"-->\n\t\t<!--\t\t\t\t></path>-->\n\t\t<!--\t\t\t</g>-->\n\t\t<!--\t\t</svg>-->\n\t</div>\n</template>\n\n<style lang=\"scss\" module>\n.handle {\n\twidth: 16px;\n\theight: 16px;\n}\n\n.circle {\n\twidth: 16px;\n\theight: 16px;\n\tborder-radius: 100%;\n\tbackground: var(--color-foreground-xdark);\n\n\t&:hover {\n\t\tbackground: var(--color-primary);\n\t}\n}\n\n.plus {\n\tposition: absolute;\n\tleft: 16px;\n\ttop: 50%;\n\ttransform: translate(0, -50%);\n\twidth: 70px;\n\theight: 24px;\n\n\t:global(.vue-flow__handle.connecting) & {\n\t\tdisplay: none;\n\t}\n}\n\n.label {\n\tposition: absolute;\n\ttop: 50%;\n\tleft: 20px;\n\ttransform: translate(0, -50%);\n\tfont-size: var(--font-size-2xs);\n\tcolor: var(--color-foreground-xdark);\n\tbackground: var(--color-background-light);\n\tz-index: 1;\n}\n</style>\n","<script lang=\"ts\" setup>\nimport { computed, inject, useCssModule } from 'vue';\nimport { CanvasNodeHandleKey } from '@/constants';\n\nconst handle = inject(CanvasNodeHandleKey);\n\nconst $style = useCssModule();\n\nconst label = computed(() => handle?.label.value ?? '');\n</script>\n<template>\n\t<div :class=\"['canvas-node-handle-non-main', $style.handle]\">\n\t\t<div :class=\"$style.diamond\" />\n\t\t<div :class=\"$style.label\">{{ label }}</div>\n\t</div>\n</template>\n\n<style lang=\"scss\" module>\n.handle {\n\twidth: 14px;\n\theight: 14px;\n\tborder-radius: 0;\n}\n\n.diamond {\n\twidth: 14px;\n\theight: 14px;\n\ttransform: rotate(45deg);\n\tbackground: hsl(\n\t\tvar(--node-type-supplemental-color-h) var(--node-type-supplemental-color-s)\n\t\t\tvar(--node-type-supplemental-color-l)\n\t);\n\n\t&:hover {\n\t\tbackground: var(--color-primary);\n\t}\n}\n\n.label {\n\tposition: absolute;\n\ttop: 18px;\n\tleft: 50%;\n\ttransform: translate(-50%, 0);\n\tfont-size: var(--font-size-2xs);\n\tcolor: var(--color-foreground-xdark);\n\tbackground: var(--color-background-light);\n\tz-index: 1;\n}\n</style>\n","<script lang=\"ts\" setup>\nimport { computed, h, provide, toRef, useCssModule } from 'vue';\nimport type { CanvasConnectionPort, CanvasElementPortWithPosition } from '@/types';\n\nimport { Handle } from '@vue-flow/core';\nimport { NodeConnectionType } from 'n8n-workflow';\nimport CanvasHandleMainInput from '@/components/canvas/elements/handles/render-types/CanvasHandleMainInput.vue';\nimport CanvasHandleMainOutput from '@/components/canvas/elements/handles/render-types/CanvasHandleMainOutput.vue';\nimport CanvasHandleNonMain from '@/components/canvas/elements/handles/render-types/CanvasHandleNonMain.vue';\nimport { CanvasNodeHandleKey } from '@/constants';\n\nconst props = defineProps<{\n\tmode: 'output' | 'input';\n\tlabel?: string;\n\ttype: CanvasConnectionPort['type'];\n\tindex: CanvasConnectionPort['index'];\n\tposition: CanvasElementPortWithPosition['position'];\n\toffset: CanvasElementPortWithPosition['offset'];\n}>();\n\nconst $style = useCssModule();\n\nconst handleType = computed(() => (props.mode === 'input' ? 'target' : 'source'));\n\nconst isConnectableStart = computed(() => {\n\treturn props.mode === 'output';\n});\n\nconst isConnectableEnd = computed(() => {\n\treturn props.mode === 'input';\n});\n\nconst Render = (renderProps: { label?: string }) => {\n\tlet Component;\n\n\tif (props.type === NodeConnectionType.Main) {\n\t\tif (props.mode === 'input') {\n\t\t\tComponent = CanvasHandleMainInput;\n\t\t} else {\n\t\t\tComponent = CanvasHandleMainOutput;\n\t\t}\n\t} else {\n\t\tComponent = CanvasHandleNonMain;\n\t}\n\n\treturn h(Component, renderProps);\n};\n\n/**\n * Provide\n */\n\nconst label = toRef(props, 'label');\n\nprovide(CanvasNodeHandleKey, {\n\tlabel,\n});\n</script>\n\n<template>\n\t<Handle\n\t\t:id=\"`${mode}s/${type}/${index}`\"\n\t\t:class=\"[$style.handle]\"\n\t\t:type=\"handleType\"\n\t\t:position=\"position\"\n\t\t:style=\"offset\"\n\t\t:connectable-start=\"isConnectableStart\"\n\t\t:connectable-end=\"isConnectableEnd\"\n\t>\n\t\t<Render :label=\"label\" />\n\t</Handle>\n</template>\n\n<style lang=\"scss\" module>\n.handle {\n\twidth: auto;\n\theight: auto;\n\tdisplay: inline-flex;\n\tjustify-content: center;\n\talign-items: center;\n\tborder: 0;\n\tbackground: none;\n\n\t> * {\n\t\tpointer-events: none;\n\t}\n}\n</style>\n","<script lang=\"ts\" setup>\nimport { Position } from '@vue-flow/core';\nimport { computed, provide, toRef } from 'vue';\nimport type {\n\tCanvasElementData,\n\tCanvasConnectionPort,\n\tCanvasElementPortWithPosition,\n} from '@/types';\nimport NodeIcon from '@/components/NodeIcon.vue';\nimport { useNodeTypesStore } from '@/stores/nodeTypes.store';\nimport CanvasNodeToolbar from '@/components/canvas/elements/nodes/CanvasNodeToolbar.vue';\nimport CanvasNodeRenderer from '@/components/canvas/elements/nodes/CanvasNodeRenderer.vue';\nimport HandleRenderer from '@/components/canvas/elements/handles/HandleRenderer.vue';\nimport { useNodeConnections } from '@/composables/useNodeConnections';\nimport { CanvasNodeKey } from '@/constants';\nimport type { NodeProps } from '@vue-flow/core';\n\nconst props = defineProps<NodeProps<CanvasElementData>>();\n\nconst inputs = computed(() => props.data.inputs);\nconst outputs = computed(() => props.data.outputs);\n\nconst nodeTypesStore = useNodeTypesStore();\n\nconst { mainInputs, nonMainInputs, mainOutputs, nonMainOutputs } = useNodeConnections({\n\tinputs,\n\toutputs,\n});\n\nconst nodeType = computed(() => {\n\treturn nodeTypesStore.getNodeType(props.data.type, props.data.typeVersion);\n});\n\n/**\n * Inputs\n */\n\nconst inputsWithPosition = computed(() => {\n\treturn [\n\t\t...mainInputs.value.map(mapEndpointWithPosition(Position.Left, 'top')),\n\t\t...nonMainInputs.value.map(mapEndpointWithPosition(Position.Bottom, 'left')),\n\t];\n});\n\n/**\n * Outputs\n */\n\nconst outputsWithPosition = computed(() => {\n\treturn [\n\t\t...mainOutputs.value.map(mapEndpointWithPosition(Position.Right, 'top')),\n\t\t...nonMainOutputs.value.map(mapEndpointWithPosition(Position.Top, 'left')),\n\t];\n});\n\n/**\n * Endpoints\n */\n\nconst mapEndpointWithPosition =\n\t(position: Position, offsetAxis: 'top' | 'left') =>\n\t(\n\t\tendpoint: CanvasConnectionPort,\n\t\tindex: number,\n\t\tendpoints: CanvasConnectionPort[],\n\t): CanvasElementPortWithPosition => {\n\t\treturn {\n\t\t\t...endpoint,\n\t\t\tposition,\n\t\t\toffset: {\n\t\t\t\t[offsetAxis]: `${(100 / (endpoints.length + 1)) * (index + 1)}%`,\n\t\t\t},\n\t\t};\n\t};\n\n/**\n * Provide\n */\n\nconst id = toRef(props, 'id');\nconst data = toRef(props, 'data');\nconst label = toRef(props, 'label');\nconst selected = toRef(props, 'selected');\n\nprovide(CanvasNodeKey, {\n\tid,\n\tdata,\n\tlabel,\n\tselected,\n\tnodeType,\n});\n</script>\n\n<template>\n\t<div :class=\"$style.canvasNode\" data-test-id=\"canvas-node\">\n\t\t<template v-for=\"source in outputsWithPosition\" :key=\"`${source.type}/${source.index}`\">\n\t\t\t<HandleRenderer\n\t\t\t\tmode=\"output\"\n\t\t\t\tdata-test-id=\"canvas-node-output-handle\"\n\t\t\t\t:type=\"source.type\"\n\t\t\t\t:label=\"source.label\"\n\t\t\t\t:index=\"source.index\"\n\t\t\t\t:position=\"source.position\"\n\t\t\t\t:offset=\"source.offset\"\n\t\t\t/>\n\t\t</template>\n\n\t\t<template v-for=\"target in inputsWithPosition\" :key=\"`${target.type}/${target.index}`\">\n\t\t\t<HandleRenderer\n\t\t\t\tmode=\"input\"\n\t\t\t\tdata-test-id=\"canvas-node-input-handle\"\n\t\t\t\t:type=\"target.type\"\n\t\t\t\t:label=\"target.label\"\n\t\t\t\t:index=\"target.index\"\n\t\t\t\t:position=\"target.position\"\n\t\t\t\t:offset=\"target.offset\"\n\t\t\t/>\n\t\t</template>\n\n\t\t<CanvasNodeToolbar\n\t\t\tv-if=\"nodeType\"\n\t\t\tdata-test-id=\"canvas-node-toolbar\"\n\t\t\t:class=\"$style.canvasNodeToolbar\"\n\t\t/>\n\n\t\t<CanvasNodeRenderer v-if=\"nodeType\">\n\t\t\t<NodeIcon :node-type=\"nodeType\" :size=\"40\" :shrink=\"false\" />\n\t\t\t<!--\t\t\t:color-default=\"iconColorDefault\"-->\n\t\t\t<!--\t\t\t:disabled=\"data.disabled\"-->\n\t\t</CanvasNodeRenderer>\n\t</div>\n</template>\n\n<style lang=\"scss\" module>\n.canvasNode {\n\t&:hover {\n\t\t.canvasNodeToolbar {\n\t\t\tdisplay: flex;\n\t\t\topacity: 1;\n\t\t}\n\t}\n}\n\n.canvasNodeToolbar {\n\tdisplay: none;\n\tposition: absolute;\n\ttop: 0;\n\tleft: 50%;\n\ttransform: translate(-50%, -100%);\n\topacity: 0;\n\ttransition: opacity 0.3s ease;\n}\n</style>\n","<script lang=\"ts\" setup>\nimport type { EdgeProps } from '@vue-flow/core';\nimport { BaseEdge, getBezierPath } from '@vue-flow/core';\nimport { computed } from 'vue';\n\nconst props = defineProps<EdgeProps>();\n\nconst edgeStyle = computed(() => ({\n\tstrokeWidth: 2,\n\t...props.style,\n}));\n\nconst path = computed(() =>\n\tgetBezierPath({\n\t\tsourceX: props.sourceX,\n\t\tsourceY: props.sourceY,\n\t\tsourcePosition: props.sourcePosition,\n\t\ttargetX: props.targetX,\n\t\ttargetY: props.targetY,\n\t\ttargetPosition: props.targetPosition,\n\t}),\n);\n</script>\n\n<template>\n\t<BaseEdge\n\t\t:id=\"id\"\n\t\t:style=\"edgeStyle\"\n\t\t:path=\"path[0]\"\n\t\t:marker-end=\"markerEnd\"\n\t\t:label=\"data?.label\"\n\t\t:label-x=\"path[1]\"\n\t\t:label-y=\"path[2]\"\n\t\t:label-style=\"{ fill: 'white' }\"\n\t\t:label-show-bg=\"true\"\n\t\t:label-bg-style=\"{ fill: 'red' }\"\n\t\t:label-bg-padding=\"[2, 4]\"\n\t\t:label-bg-border-radius=\"2\"\n\t/>\n</template>\n","<script lang=\"ts\" setup>\nimport type { CanvasConnection, CanvasElement } from '@/types';\nimport type { NodeDragEvent, Connection } from '@vue-flow/core';\nimport { VueFlow, PanelPosition } from '@vue-flow/core';\nimport { Background } from '@vue-flow/background';\nimport { Controls } from '@vue-flow/controls';\nimport { MiniMap } from '@vue-flow/minimap';\nimport CanvasNode from './elements/nodes/CanvasNode.vue';\nimport CanvasEdge from './elements/edges/CanvasEdge.vue';\nimport { useCssModule } from 'vue';\n\nconst $style = useCssModule();\n\nconst emit = defineEmits<{\n\t'update:modelValue': [elements: CanvasElement[]];\n\t'update:node:position': [id: string, position: { x: number; y: number }];\n\t'create:connection': [connection: Connection];\n}>();\n\nwithDefaults(\n\tdefineProps<{\n\t\tid?: string;\n\t\telements: CanvasElement[];\n\t\tconnections: CanvasConnection[];\n\t\tcontrolsPosition?: PanelPosition;\n\t}>(),\n\t{\n\t\tid: 'canvas',\n\t\telements: () => [],\n\t\tconnections: () => [],\n\t\tcontrolsPosition: PanelPosition.BottomLeft,\n\t},\n);\n\nfunction onNodeDragStop(e: NodeDragEvent) {\n\te.nodes.forEach((node) => {\n\t\temit('update:node:position', node.id, node.position);\n\t});\n}\n\nfunction onConnect(...args: unknown[]) {\n\temit('create:connection', args[0] as Connection);\n}\n</script>\n\n<template>\n\t<VueFlow\n\t\t:id=\"id\"\n\t\t:nodes=\"elements\"\n\t\t:edges=\"connections\"\n\t\t:apply-changes=\"false\"\n\t\tfit-view-on-init\n\t\tpan-on-scroll\n\t\t:min-zoom=\"0.2\"\n\t\t:max-zoom=\"2\"\n\t\tdata-test-id=\"canvas\"\n\t\t@node-drag-stop=\"onNodeDragStop\"\n\t\t@connect=\"onConnect\"\n\t>\n\t\t<template #node-canvas-node=\"canvasNodeProps\">\n\t\t\t<CanvasNode v-bind=\"canvasNodeProps\" />\n\t\t</template>\n\n\t\t<template #edge-canvas-edge=\"canvasEdgeProps\">\n\t\t\t<CanvasEdge v-bind=\"canvasEdgeProps\" />\n\t\t</template>\n\n\t\t<Background data-test-id=\"canvas-background\" pattern-color=\"#aaa\" :gap=\"16\" />\n\n\t\t<MiniMap data-test-id=\"canvas-minimap\" pannable />\n\n\t\t<Controls\n\t\t\tdata-test-id=\"canvas-controls\"\n\t\t\t:class=\"$style.canvasControls\"\n\t\t\t:position=\"controlsPosition\"\n\t\t></Controls>\n\t</VueFlow>\n</template>\n\n<style lang=\"scss\" module></style>\n\n<style lang=\"scss\">\n.vue-flow__controls {\n\tdisplay: flex;\n\tgap: var(--spacing-2xs);\n\tbox-shadow: none;\n}\n\n.vue-flow__controls-button {\n\twidth: 42px;\n\theight: 42px;\n\tborder: var(--border-base);\n\tborder-radius: var(--border-radius-base);\n\tpadding: 0;\n\ttransition-property: transform, background, border, color;\n\ttransition-duration: 300ms;\n\ttransition-timing-function: ease;\n\n\t&:hover {\n\t\tborder-color: var(--color-button-secondary-hover-active-border);\n\t\tbackground-color: var(--color-button-secondary-active-background);\n\t\ttransform: scale(1.1);\n\n\t\tsvg {\n\t\t\tfill: var(--color-primary);\n\t\t}\n\t}\n\n\tsvg {\n\t\tmax-height: 16px;\n\t\tmax-width: 16px;\n\t\ttransition-property: fill;\n\t\ttransition-duration: 300ms;\n\t\ttransition-timing-function: ease;\n\t}\n}\n</style>\n","import type { IConnections, INodeTypeDescription } from 'n8n-workflow';\nimport type { INodeUi } from '@/Interface';\nimport type { CanvasConnection, CanvasConnectionPortType, CanvasConnectionPort } from '@/types';\nimport { v4 as uuid } from 'uuid';\n\nexport function mapLegacyConnectionsToCanvasConnections(\n\tlegacyConnections: IConnections,\n\tnodes: INodeUi[],\n): CanvasConnection[] {\n\tconst mappedConnections: CanvasConnection[] = [];\n\n\tObject.keys(legacyConnections).forEach((fromNodeName) => {\n\t\tconst fromId = nodes.find((node) => node.name === fromNodeName)?.id;\n\t\tconst fromConnectionTypes = Object.keys(legacyConnections[fromNodeName]);\n\n\t\tfromConnectionTypes.forEach((fromConnectionType) => {\n\t\t\tconst fromPorts = legacyConnections[fromNodeName][fromConnectionType];\n\t\t\tfromPorts.forEach((toPorts, fromIndex) => {\n\t\t\t\ttoPorts.forEach((toPort) => {\n\t\t\t\t\tconst toId = nodes.find((node) => node.name === toPort.node)?.id;\n\t\t\t\t\tconst toConnectionType = toPort.type;\n\t\t\t\t\tconst toIndex = toPort.index;\n\n\t\t\t\t\tif (fromId && toId) {\n\t\t\t\t\t\tmappedConnections.push({\n\t\t\t\t\t\t\tid: `[${fromId}/${fromConnectionType}/${fromIndex}][${toId}/${toConnectionType}/${toIndex}]`,\n\t\t\t\t\t\t\tsource: fromId,\n\t\t\t\t\t\t\ttarget: toId,\n\t\t\t\t\t\t\tsourceHandle: `outputs/${fromConnectionType}/${fromIndex}`,\n\t\t\t\t\t\t\ttargetHandle: `inputs/${toConnectionType}/${toIndex}`,\n\t\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\t\tfromNodeName,\n\t\t\t\t\t\t\t\tsource: {\n\t\t\t\t\t\t\t\t\tindex: fromIndex,\n\t\t\t\t\t\t\t\t\ttype: fromConnectionType as CanvasConnectionPortType,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\ttarget: {\n\t\t\t\t\t\t\t\t\tindex: toIndex,\n\t\t\t\t\t\t\t\t\ttype: toConnectionType as CanvasConnectionPortType,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t});\n\t\t});\n\t});\n\n\treturn mappedConnections;\n}\n\nexport function mapLegacyEndpointsToCanvasConnectionPort(\n\tendpoints: INodeTypeDescription['inputs'],\n): CanvasConnectionPort[] {\n\tif (typeof endpoints === 'string') {\n\t\tconsole.warn('Node endpoints have not been evaluated', endpoints);\n\t\treturn [];\n\t}\n\n\treturn endpoints.map((endpoint, endpointIndex) => {\n\t\tconst type = typeof endpoint === 'string' ? endpoint : endpoint.type;\n\t\tconst label = typeof endpoint === 'string' ? undefined : endpoint.displayName;\n\t\tconst index =\n\t\t\tendpoints\n\t\t\t\t.slice(0, endpointIndex + 1)\n\t\t\t\t.filter((e) => (typeof e === 'string' ? e : e.type) === type).length - 1;\n\t\tconst required = typeof endpoint === 'string' ? false : endpoint.required;\n\n\t\treturn {\n\t\t\ttype,\n\t\t\tindex,\n\t\t\tlabel,\n\t\t\t...(required ? { required } : {}),\n\t\t};\n\t});\n}\n\nexport function getUniqueNodeName(name: string, existingNames: Set<string>): string {\n\tif (!existingNames.has(name)) {\n\t\treturn name;\n\t}\n\n\tfor (let i = 1; i < 100; i++) {\n\t\tconst newName = `${name} ${i}`;\n\t\tif (!existingNames.has(newName)) {\n\t\t\treturn newName;\n\t\t}\n\t}\n\n\treturn `${name} ${uuid()}`;\n}\n","import { useI18n } from '@/composables/useI18n';\nimport { useNodeTypesStore } from '@/stores/nodeTypes.store';\nimport type { Ref } from 'vue';\nimport { computed } from 'vue';\nimport type {\n\tCanvasConnection,\n\tCanvasConnectionPort,\n\tCanvasElement,\n\tCanvasElementData,\n} from '@/types';\nimport {\n\tmapLegacyConnectionsToCanvasConnections,\n\tmapLegacyEndpointsToCanvasConnectionPort,\n} from '@/utils/canvasUtilsV2';\nimport type { Workflow } from 'n8n-workflow';\nimport { NodeHelpers } from 'n8n-workflow';\nimport type { IWorkflowDb } from '@/Interface';\n\nexport function useCanvasMapping({\n\tworkflow,\n\tworkflowObject,\n}: {\n\tworkflow: Ref<IWorkflowDb>;\n\tworkflowObject: Ref<Workflow>;\n}) {\n\tconst locale = useI18n();\n\tconst nodeTypesStore = useNodeTypesStore();\n\n\tconst renderTypeByNodeType = computed(\n\t\t() =>\n\t\t\tworkflow.value.nodes.reduce<Record<string, CanvasElementData['renderType']>>((acc, node) => {\n\t\t\t\tlet renderType: CanvasElementData['renderType'] = 'default';\n\t\t\t\tswitch (true) {\n\t\t\t\t\tcase nodeTypesStore.isTriggerNode(node.type):\n\t\t\t\t\t\trenderType = 'trigger';\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase nodeTypesStore.isConfigNode(workflowObject.value, node, node.type):\n\t\t\t\t\t\trenderType = 'configuration';\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase nodeTypesStore.isConfigurableNode(workflowObject.value, node, node.type):\n\t\t\t\t\t\trenderType = 'configurable';\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tacc[node.type] = renderType;\n\t\t\t\treturn acc;\n\t\t\t}, {}) ?? {},\n\t);\n\n\tconst nodeInputsById = computed(() =>\n\t\tworkflow.value.nodes.reduce<Record<string, CanvasConnectionPort[]>>((acc, node) => {\n\t\t\tconst nodeTypeDescription = nodeTypesStore.getNodeType(node.type);\n\t\t\tconst workflowObjectNode = workflowObject.value.getNode(node.name);\n\n\t\t\tacc[node.id] =\n\t\t\t\tworkflowObjectNode && nodeTypeDescription\n\t\t\t\t\t? mapLegacyEndpointsToCanvasConnectionPort(\n\t\t\t\t\t\t\tNodeHelpers.getNodeInputs(\n\t\t\t\t\t\t\t\tworkflowObject.value,\n\t\t\t\t\t\t\t\tworkflowObjectNode,\n\t\t\t\t\t\t\t\tnodeTypeDescription,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t)\n\t\t\t\t\t: [];\n\n\t\t\treturn acc;\n\t\t}, {}),\n\t);\n\n\tconst nodeOutputsById = computed(() =>\n\t\tworkflow.value.nodes.reduce<Record<string, CanvasConnectionPort[]>>((acc, node) => {\n\t\t\tconst nodeTypeDescription = nodeTypesStore.getNodeType(node.type);\n\t\t\tconst workflowObjectNode = workflowObject.value.getNode(node.name);\n\n\t\t\tacc[node.id] =\n\t\t\t\tworkflowObjectNode && nodeTypeDescription\n\t\t\t\t\t? mapLegacyEndpointsToCanvasConnectionPort(\n\t\t\t\t\t\t\tNodeHelpers.getNodeOutputs(\n\t\t\t\t\t\t\t\tworkflowObject.value,\n\t\t\t\t\t\t\t\tworkflowObjectNode,\n\t\t\t\t\t\t\t\tnodeTypeDescription,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t)\n\t\t\t\t\t: [];\n\n\t\t\treturn acc;\n\t\t}, {}),\n\t);\n\n\tconst elements = computed<CanvasElement[]>(() => [\n\t\t...workflow.value.nodes.map<CanvasElement>((node) => {\n\t\t\tconst data: CanvasElementData = {\n\t\t\t\tid: node.id,\n\t\t\t\ttype: node.type,\n\t\t\t\ttypeVersion: node.typeVersion,\n\t\t\t\tinputs: nodeInputsById.value[node.id] ?? [],\n\t\t\t\toutputs: nodeOutputsById.value[node.id] ?? [],\n\t\t\t\trenderType: renderTypeByNodeType.value[node.type] ?? 'default',\n\t\t\t};\n\n\t\t\treturn {\n\t\t\t\tid: node.id,\n\t\t\t\tlabel: node.name,\n\t\t\t\ttype: 'canvas-node',\n\t\t\t\tposition: { x: node.position[0], y: node.position[1] },\n\t\t\t\tdata,\n\t\t\t};\n\t\t}),\n\t]);\n\n\tconst connections = computed<CanvasConnection[]>(() => {\n\t\tconst mappedConnections = mapLegacyConnectionsToCanvasConnections(\n\t\t\tworkflow.value.connections ?? [],\n\t\t\tworkflow.value.nodes ?? [],\n\t\t);\n\n\t\treturn mappedConnections.map((connection) => {\n\t\t\tconst type = getConnectionType(connection);\n\t\t\tconst label = getConnectionLabel(connection);\n\n\t\t\treturn {\n\t\t\t\t...connection,\n\t\t\t\ttype,\n\t\t\t\tlabel,\n\t\t\t};\n\t\t});\n\t});\n\n\tfunction getConnectionType(_: CanvasConnection): string {\n\t\treturn 'canvas-edge';\n\t}\n\n\tfunction getConnectionLabel(connection: CanvasConnection): string {\n\t\tconst pinData = workflow.value.pinData?.[connection.data?.fromNodeName ?? ''];\n\n\t\tif (pinData?.length) {\n\t\t\treturn locale.baseText('ndv.output.items', {\n\t\t\t\tadjustToNumber: pinData.length,\n\t\t\t\tinterpolate: { count: String(pinData.length) },\n\t\t\t});\n\t\t}\n\n\t\treturn '';\n\t}\n\n\treturn {\n\t\tconnections,\n\t\telements,\n\t};\n}\n","<script setup lang=\"ts\">\nimport Canvas from '@/components/canvas/Canvas.vue';\nimport { toRef, useCssModule } from 'vue';\nimport type { Workflow } from 'n8n-workflow';\nimport type { IWorkflowDb } from '@/Interface';\nimport { useCanvasMapping } from '@/composables/useCanvasMapping';\n\nconst props = defineProps<{\n\tid?: string;\n\tworkflow: IWorkflowDb;\n\tworkflowObject: Workflow;\n}>();\n\nconst $style = useCssModule();\n\nconst workflow = toRef(props, 'workflow');\nconst workflowObject = toRef(props, 'workflowObject');\n\nconst { elements, connections } = useCanvasMapping({ workflow, workflowObject });\n</script>\n\n<template>\n\t<div :class=\"$style.wrapper\">\n\t\t<div :class=\"$style.canvas\">\n\t\t\t<Canvas v-if=\"workflow\" :elements=\"elements\" :connections=\"connections\" v-bind=\"$attrs\" />\n\t\t</div>\n\t\t<slot />\n\t</div>\n</template>\n\n<style lang=\"scss\" module>\n.wrapper {\n\tdisplay: block;\n\tposition: relative;\n\twidth: 100%;\n\theight: 100%;\n\toverflow: hidden;\n}\n\n.canvas {\n\twidth: 100%;\n\theight: 100%;\n\tposition: relative;\n\tdisplay: block;\n}\n\n.executionButtons {\n\tposition: absolute;\n\tdisplay: flex;\n\tjustify-content: center;\n\talign-items: center;\n\tleft: 50%;\n\ttransform: translateX(-50%);\n\tbottom: var(--spacing-l);\n\twidth: auto;\n\n\t@media (max-width: $breakpoint-2xs) {\n\t\tbottom: 150px;\n\t}\n\n\tbutton {\n\t\tdisplay: flex;\n\t\tjustify-content: center;\n\t\talign-items: center;\n\t\tmargin-left: 0.625rem;\n\n\t\t&:first-child {\n\t\t\tmargin: 0;\n\t\t}\n\t}\n}\n</style>\n","<script setup lang=\"ts\">\nimport KeyboardShortcutTooltip from '@/components/KeyboardShortcutTooltip.vue';\nimport { computed } from 'vue';\nimport { useI18n } from '@/composables/useI18n';\nimport { useUIStore } from '@/stores/ui.store';\n\ndefineEmits(['click']);\n\nconst uiStore = useUIStore();\nconst locale = useI18n();\n\nconst workflowRunning = computed(() => uiStore.isActionActive('workflowRunning'));\n\nconst runButtonText = computed(() => {\n\tif (!workflowRunning.value) {\n\t\treturn locale.baseText('nodeView.runButtonText.executeWorkflow');\n\t}\n\n\treturn locale.baseText('nodeView.runButtonText.executingWorkflow');\n});\n</script>\n\n<template>\n\t<KeyboardShortcutTooltip :label=\"runButtonText\" :shortcut=\"{ metaKey: true, keys: ['↵'] }\">\n\t\t<N8nButton\n\t\t\t:loading=\"workflowRunning\"\n\t\t\t:label=\"runButtonText\"\n\t\t\tsize=\"large\"\n\t\t\ticon=\"flask\"\n\t\t\ttype=\"primary\"\n\t\t\tdata-test-id=\"execute-workflow-button\"\n\t\t\t@click.stop=\"$emit('click', $event)\"\n\t\t/>\n\t</KeyboardShortcutTooltip>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, defineAsyncComponent, onMounted, ref, useCssModule } from 'vue';\nimport { useRoute, useRouter } from 'vue-router';\nimport WorkflowCanvas from '@/components/canvas/WorkflowCanvas.vue';\nimport { useNodeTypesStore } from '@/stores/nodeTypes.store';\nimport { useUIStore } from '@/stores/ui.store';\nimport CanvasExecuteWorkflowButton from '@/components/canvas/elements/buttons/CanvasExecuteWorkflowButton.vue';\nimport { useI18n } from '@/composables/useI18n';\nimport { useWorkflowsStore } from '@/stores/workflows.store';\nimport { useRunWorkflow } from '@/composables/useRunWorkflow';\nimport type {\n\tAddedNodesAndConnections,\n\tINodeUi,\n\tITag,\n\tToggleNodeCreatorOptions,\n\tXYPosition,\n} from '@/Interface';\nimport useWorkflowsEEStore from '@/stores/workflows.ee.store';\nimport { useTagsStore } from '@/stores/tags.store';\nimport type { Connection } from '@vue-flow/core';\nimport type { CanvasElement } from '@/types';\nimport {\n\tEnterpriseEditionFeature,\n\tAI_NODE_CREATOR_VIEW,\n\tREGULAR_NODE_CREATOR_VIEW,\n\tTRIGGER_NODE_CREATOR_VIEW,\n\tVIEWS,\n} from '@/constants';\nimport { useSourceControlStore } from '@/stores/sourceControl.store';\nimport { useNodeCreatorStore } from '@/stores/nodeCreator.store';\nimport { useTelemetry } from '@/composables/useTelemetry';\nimport { useExternalHooks } from '@/composables/useExternalHooks';\nimport * as NodeViewUtils from '@/utils/nodeViewUtils';\nimport type { INodeTypeDescription } from 'n8n-workflow';\nimport { NodeConnectionType } from 'n8n-workflow';\nimport { useToast } from '@/composables/useToast';\nimport { v4 as uuid } from 'uuid';\nimport { useSettingsStore } from '@/stores/settings.store';\nimport { useCredentialsStore } from '@/stores/credentials.store';\nimport useEnvironmentsStore from '@/stores/environments.ee.store';\nimport { useExternalSecretsStore } from '@/stores/externalSecrets.ee.store';\nimport { useRootStore } from '@/stores/n8nRoot.store';\nimport { useCollaborationStore } from '@/stores/collaboration.store';\nimport { getUniqueNodeName } from '@/utils/canvasUtilsV2';\n\nconst NodeCreation = defineAsyncComponent(\n\tasync () => await import('@/components/Node/NodeCreation.vue'),\n);\n\nconst $style = useCssModule();\n\nconst router = useRouter();\nconst route = useRoute();\nconst i18n = useI18n();\nconst telemetry = useTelemetry();\nconst externalHooks = useExternalHooks();\nconst toast = useToast();\n\nconst nodeTypesStore = useNodeTypesStore();\nconst uiStore = useUIStore();\nconst workflowsStore = useWorkflowsStore();\nconst workflowsEEStore = useWorkflowsEEStore();\nconst tagsStore = useTagsStore();\nconst sourceControlStore = useSourceControlStore();\nconst nodeCreatorStore = useNodeCreatorStore();\nconst settingsStore = useSettingsStore();\nconst credentialsStore = useCredentialsStore();\nconst environmentsStore = useEnvironmentsStore();\nconst externalSecretsStore = useExternalSecretsStore();\nconst rootStore = useRootStore();\nconst collaborationStore = useCollaborationStore();\n\nconst { runWorkflow } = useRunWorkflow({ router });\n\nconst isLoading = ref(true);\nconst readOnlyNotification = ref<null | { visible: boolean }>(null);\n\nconst workflowId = computed<string>(() => route.params.workflowId as string);\nconst workflow = computed(() => workflowsStore.workflowsById[workflowId.value]);\n\nconst editableWorkflow = computed(() => workflowsStore.workflow);\nconst editableWorkflowObject = computed(() => workflowsStore.getCurrentWorkflow());\n\nconst isDemoRoute = computed(() => route.name === VIEWS.DEMO);\nconst isReadOnlyRoute = computed(() => route?.meta?.readOnlyCanvas === true);\nconst isReadOnlyEnvironment = computed(() => {\n\treturn sourceControlStore.preferences.branchReadOnly;\n});\n\nconst triggerNodes = computed<INodeUi[]>(() => {\n\treturn workflowsStore.workflowTriggerNodes;\n});\n\nconst isCanvasAddButtonVisible = computed(() => {\n\treturn (\n\t\ttriggerNodes.value.length > 0 &&\n\t\t!isLoading.value &&\n\t\t!isDemoRoute.value &&\n\t\t!isReadOnlyEnvironment.value\n\t);\n});\n\nonMounted(() => {\n\tvoid initialize();\n});\n\nasync function initialize() {\n\tisLoading.value = true;\n\n\tconst loadPromises: Array<Promise<unknown>> = [\n\t\tnodeTypesStore.getNodeTypes(),\n\t\tworkflowsStore.fetchWorkflow(workflowId.value),\n\t];\n\n\tif (!settingsStore.isPreviewMode && !isDemoRoute.value) {\n\t\tloadPromises.push(\n\t\t\tworkflowsStore.fetchActiveWorkflows(),\n\t\t\tcredentialsStore.fetchAllCredentials(),\n\t\t\tcredentialsStore.fetchCredentialTypes(true),\n\t\t);\n\n\t\tif (settingsStore.isEnterpriseFeatureEnabled(EnterpriseEditionFeature.Variables)) {\n\t\t\tloadPromises.push(environmentsStore.fetchAllVariables());\n\t\t}\n\n\t\tif (settingsStore.isEnterpriseFeatureEnabled(EnterpriseEditionFeature.ExternalSecrets)) {\n\t\t\tloadPromises.push(externalSecretsStore.fetchAllSecrets());\n\t\t}\n\t}\n\n\ttry {\n\t\tawait Promise.all(loadPromises);\n\t} catch (error) {\n\t\treturn toast.showError(\n\t\t\terror,\n\t\t\ti18n.baseText('nodeView.showError.mounted1.title'),\n\t\t\ti18n.baseText('nodeView.showError.mounted1.message') + ':',\n\t\t);\n\t}\n\n\tinitializeEditableWorkflow(workflowId.value);\n\n\tif (window.parent) {\n\t\twindow.parent.postMessage(\n\t\t\tJSON.stringify({ command: 'n8nReady', version: rootStore.versionCli }),\n\t\t\t'*',\n\t\t);\n\t}\n\n\tisLoading.value = false;\n}\n\n// @TODO Maybe move this to the store\nfunction initializeEditableWorkflow(id: string) {\n\tconst targetWorkflow = workflowsStore.workflowsById[id];\n\n\tworkflowsStore.addWorkflow(targetWorkflow);\n\tworkflowsStore.setWorkflow(targetWorkflow);\n\tworkflowsStore.setActive(targetWorkflow.active || false);\n\tworkflowsStore.setWorkflowId(targetWorkflow.id);\n\tworkflowsStore.setWorkflowName({ newName: targetWorkflow.name, setStateDirty: false });\n\tworkflowsStore.setWorkflowSettings(targetWorkflow.settings ?? {});\n\tworkflowsStore.setWorkflowPinData(targetWorkflow.pinData ?? {});\n\tworkflowsStore.setWorkflowVersionId(targetWorkflow.versionId);\n\tworkflowsStore.setWorkflowMetadata(targetWorkflow.meta);\n\tif (targetWorkflow.usedCredentials) {\n\t\tworkflowsStore.setUsedCredentials(targetWorkflow.usedCredentials);\n\t}\n\n\tconst tags = (targetWorkflow.tags ?? []) as ITag[];\n\tconst tagIds = tags.map((tag) => tag.id);\n\tworkflowsStore.setWorkflowTagIds(tagIds || []);\n\ttagsStore.upsertTags(tags);\n\n\t// @TODO Figure out a better way to handle this. Maybe show a message on why the state becomes dirty\n\t// if (!this.credentialsUpdated) {\n\t// \tthis.uiStore.stateIsDirty = false;\n\t// }\n\n\tvoid externalHooks.run('workflow.open', {\n\t\tworkflowId: workflow.value.id,\n\t\tworkflowName: workflow.value.name,\n\t});\n\n\t// @TODO Figure out a better way to handle this\n\t// if (selectedExecution?.workflowId !== workflow.id) {\n\t// \tthis.executionsStore.activeExecution = null;\n\t// \tworkflowsStore.currentWorkflowExecutions = [];\n\t// } else {\n\t// \tthis.executionsStore.activeExecution = selectedExecution;\n\t// }\n\n\tcollaborationStore.notifyWorkflowOpened(workflow.value.id);\n}\n\nasync function onRunWorkflow() {\n\tawait runWorkflow({});\n}\n\n/**\n * Map new node position format to the old one and update the store\n *\n * @param id\n * @param position\n */\nfunction onNodePositionUpdate(id: string, position: CanvasElement['position']) {\n\tworkflowsStore.setNodePosition(id, [position.x, position.y]);\n}\n\n/**\n * Map new node connection format to the old one and add it to the store\n *\n * @param connection\n */\nfunction onCreateNodeConnection(connection: Connection) {\n\t// Output\n\tconst sourceNodeId = connection.source;\n\tconst sourceNode = workflowsStore.getNodeById(sourceNodeId);\n\tconst sourceNodeName = sourceNode?.name ?? '';\n\tconst [, sourceType, sourceIndex] = (connection.sourceHandle ?? '').split('/');\n\n\t// Input\n\tconst targetNodeId = connection.target;\n\tconst targetNode = workflowsStore.getNodeById(targetNodeId);\n\tconst targetNodeName = targetNode?.name ?? '';\n\tconst [, targetType, targetIndex] = (connection.targetHandle ?? '').split('/');\n\n\tif (sourceNode && targetNode && !checkIfNodeConnectionIsAllowed(sourceNode, targetNode)) {\n\t\treturn;\n\t}\n\n\tworkflowsStore.addConnection({\n\t\tconnection: [\n\t\t\t{\n\t\t\t\tnode: sourceNodeName,\n\t\t\t\ttype: sourceType,\n\t\t\t\tindex: parseInt(sourceIndex, 10),\n\t\t\t},\n\t\t\t{\n\t\t\t\tnode: targetNodeName,\n\t\t\t\ttype: targetType,\n\t\t\t\tindex: parseInt(targetIndex, 10),\n\t\t\t},\n\t\t],\n\t});\n\n\tuiStore.stateIsDirty = true;\n}\n\n// @TODO Figure out a way to improve this\nfunction checkIfNodeConnectionIsAllowed(sourceNode: INodeUi, targetNode: INodeUi): boolean {\n\t// const targetNodeType = nodeTypesStore.getNodeType(\n\t// \ttargetNode.type,\n\t// \ttargetNode.typeVersion,\n\t// );\n\t//\n\t// if (targetNodeType?.inputs?.length) {\n\t// \tconst workflow = this.workflowHelpers.getCurrentWorkflow();\n\t// \tconst workflowNode = workflow.getNode(targetNode.name);\n\t// \tlet inputs: Array<ConnectionTypes | INodeInputConfiguration> = [];\n\t// \tif (targetNodeType) {\n\t// \t\tinputs = NodeHelpers.getNodeInputs(workflow, workflowNode, targetNodeType);\n\t// \t}\n\t//\n\t// \tfor (const input of inputs || []) {\n\t// \t\tif (typeof input === 'string' || input.type !== targetInfoType || !input.filter) {\n\t// \t\t\t// No filters defined or wrong connection type\n\t// \t\t\tcontinue;\n\t// \t\t}\n\t//\n\t// \t\tif (input.filter.nodes.length) {\n\t// \t\t\tif (!input.filter.nodes.includes(sourceNode.type)) {\n\t// \t\t\t\tthis.dropPrevented = true;\n\t// \t\t\t\tthis.showToast({\n\t// \t\t\t\t\ttitle: this.$locale.baseText('nodeView.showError.nodeNodeCompatible.title'),\n\t// \t\t\t\t\tmessage: this.$locale.baseText('nodeView.showError.nodeNodeCompatible.message', {\n\t// \t\t\t\t\t\tinterpolate: { sourceNodeName: sourceNode.name, targetNodeName: targetNode.name },\n\t// \t\t\t\t\t}),\n\t// \t\t\t\t\ttype: 'error',\n\t// \t\t\t\t\tduration: 5000,\n\t// \t\t\t\t});\n\t// \t\t\t\treturn false;\n\t// \t\t\t}\n\t// \t\t}\n\t// \t}\n\t// }\n\treturn true;\n}\n\nfunction onToggleNodeCreator({\n\tsource,\n\tcreateNodeActive,\n\tnodeCreatorView,\n}: ToggleNodeCreatorOptions) {\n\tif (createNodeActive === uiStore.isCreateNodeActive) {\n\t\treturn;\n\t}\n\n\tif (!nodeCreatorView) {\n\t\tnodeCreatorView =\n\t\t\ttriggerNodes.value.length > 0 ? REGULAR_NODE_CREATOR_VIEW : TRIGGER_NODE_CREATOR_VIEW;\n\t}\n\t// Default to the trigger tab in node creator if there's no trigger node yet\n\tnodeCreatorStore.setSelectedView(nodeCreatorView);\n\n\tlet mode;\n\tswitch (nodeCreatorStore.selectedView) {\n\t\tcase AI_NODE_CREATOR_VIEW:\n\t\t\tmode = 'ai';\n\t\t\tbreak;\n\t\tcase REGULAR_NODE_CREATOR_VIEW:\n\t\t\tmode = 'regular';\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tmode = 'regular';\n\t}\n\n\tuiStore.isCreateNodeActive = createNodeActive;\n\tif (createNodeActive && source) {\n\t\tnodeCreatorStore.setOpenSource(source);\n\t}\n\n\tvoid externalHooks.run('nodeView.createNodeActiveChanged', {\n\t\tsource,\n\t\tmode,\n\t\tcreateNodeActive,\n\t});\n\n\ttelemetry.trackNodesPanel('nodeView.createNodeActiveChanged', {\n\t\tsource,\n\t\tmode,\n\t\tcreateNodeActive,\n\t\tworkflow_id: workflowId.value,\n\t});\n}\n\nasync function onAddNodes(\n\t{ nodes, connections }: AddedNodesAndConnections,\n\tdragAndDrop = false,\n\tposition?: XYPosition,\n) {\n\tlet currentPosition = position;\n\tfor (const { type, name, position: nodePosition, isAutoAdd, openDetail } of nodes) {\n\t\tconst node = await addNode(\n\t\t\t{\n\t\t\t\tname,\n\t\t\t\ttype,\n\t\t\t\tposition: nodePosition ?? currentPosition,\n\t\t\t},\n\t\t\t{\n\t\t\t\tdragAndDrop,\n\t\t\t\topenNDV: openDetail ?? false,\n\t\t\t\ttrackHistory: true,\n\t\t\t\tisAutoAdd,\n\t\t\t},\n\t\t);\n\n\t\tconst lastAddedNode = editableWorkflow.value.nodes[editableWorkflow.value.nodes.length - 1];\n\t\tcurrentPosition = [\n\t\t\tlastAddedNode.position[0] + NodeViewUtils.NODE_SIZE * 2 + NodeViewUtils.GRID_SIZE,\n\t\t\tlastAddedNode.position[1],\n\t\t];\n\t}\n\n\tconst newNodesOffset = editableWorkflow.value.nodes.length - nodes.length;\n\tfor (const { from, to } of connections) {\n\t\tconst fromNode = editableWorkflow.value.nodes[newNodesOffset + from.nodeIndex];\n\t\tconst toNode = editableWorkflow.value.nodes[newNodesOffset + to.nodeIndex];\n\n\t\tonCreateNodeConnection({\n\t\t\tsource: fromNode.id,\n\t\t\tsourceHandle: `outputs/${NodeConnectionType.Main}/${from.outputIndex ?? 0}`,\n\t\t\ttarget: toNode.id,\n\t\t\ttargetHandle: `inputs/${NodeConnectionType.Main}/${to.inputIndex ?? 0}`,\n\t\t});\n\t}\n\n\t// @TODO Implement this\n\t// const lastAddedNode = editableWorkflow.value.nodes[editableWorkflow.value.nodes.length - 1];\n\t// const workflow = editableWorkflowObject.value;\n\t// const lastNodeInputs = workflow.getParentNodesByDepth(lastAddedNode.name, 1);\n\t//\n\t// // If the last added node has multiple inputs, move them down\n\t// if (lastNodeInputs.length > 1) {\n\t// \tlastNodeInputs.slice(1).forEach((node, index) => {\n\t// \t\tconst nodeUi = workflowsStore.getNodeByName(node.name);\n\t// \t\tif (!nodeUi) return;\n\t//\n\t// \t\t// onMoveNode({\n\t// \t\t// \tnodeName: nodeUi.name,\n\t// \t\t// \tposition: [nodeUi.position[0], nodeUi.position[1] + 100 * (index + 1)],\n\t// \t\t// });\n\t// \t});\n\t// }\n}\n\ntype AddNodeData = {\n\tname?: string;\n\ttype: string;\n\tposition?: XYPosition;\n};\n\ntype AddNodeOptions = {\n\tdragAndDrop?: boolean;\n\topenNDV?: boolean;\n\ttrackHistory?: boolean;\n\tisAutoAdd?: boolean;\n};\n\nasync function addNode(node: AddNodeData, options: AddNodeOptions): Promise<INodeUi | undefined> {\n\tif (!checkIfEditingIsAllowed()) {\n\t\treturn;\n\t}\n\n\tconst newNodeData = await createNodeWithDefaultCredentials(node);\n\tif (!newNodeData) {\n\t\treturn;\n\t}\n\n\t/**\n\t * @TODO Check if maximum node type limit reached\n\t */\n\n\tnewNodeData.name = getUniqueNodeName(newNodeData.name, workflowsStore.canvasNames);\n\n\tworkflowsStore.addNode(newNodeData);\n\n\t// @TODO Figure out why this is needed and if we can do better...\n\t// this.matchCredentials(node);\n\n\t// const lastSelectedNode = uiStore.getLastSelectedNode;\n\t// const lastSelectedNodeOutputIndex = uiStore.lastSelectedNodeOutputIndex;\n\t// const lastSelectedNodeEndpointUuid = uiStore.lastSelectedNodeEndpointUuid;\n\t// const lastSelectedConnection = canvasStore.lastSelectedConnection;\n\t//\n\t// historyStore.startRecordingUndo();\n\t//\n\t// const newNodeData = await injectNode(\n\t// \tnodeTypeName,\n\t// \toptions,\n\t// \tshowDetail,\n\t// \ttrackHistory,\n\t// \tisAutoAdd,\n\t// );\n\t// if (!newNodeData) {\n\t// \treturn;\n\t// }\n\t//\n\t// const outputIndex = lastSelectedNodeOutputIndex || 0;\n\t// const targetEndpoint = lastSelectedNodeEndpointUuid || '';\n\t//\n\t// // Handle connection of scoped_endpoint types\n\t// if (lastSelectedNodeEndpointUuid && !isAutoAdd) {\n\t// \tconst lastSelectedEndpoint = this.instance.getEndpoint(lastSelectedNodeEndpointUuid);\n\t// \tif (\n\t// \t\tlastSelectedEndpoint &&\n\t// \t\tthis.checkNodeConnectionAllowed(\n\t// \t\t\tlastSelectedNode,\n\t// \t\t\tnewNodeData,\n\t// \t\t\tlastSelectedEndpoint.scope as NodeConnectionType,\n\t// \t\t)\n\t// \t) {\n\t// \t\tconst connectionType = lastSelectedEndpoint.scope as ConnectionTypes;\n\t// \t\tconst newNodeElement = this.instance.getManagedElement(newNodeData.id);\n\t// \t\tconst newNodeConnections = this.instance.getEndpoints(newNodeElement);\n\t// \t\tconst viableConnection = newNodeConnections.find((conn) => {\n\t// \t\t\treturn (\n\t// \t\t\t\tconn.scope === connectionType &&\n\t// \t\t\t\tlastSelectedEndpoint.parameters.connection !== conn.parameters.connection\n\t// \t\t\t);\n\t// \t\t});\n\t//\n\t// \t\tthis.instance?.connect({\n\t// \t\t\tuuids: [targetEndpoint, viableConnection?.uuid || ''],\n\t// \t\t\tdetachable: !this.isReadOnlyRoute && !this.readOnlyEnv,\n\t// \t\t});\n\t// \t\tthis.historyStore.stopRecordingUndo();\n\t// \t\treturn;\n\t// \t}\n\t// }\n\t// If a node is last selected then connect between the active and its child ones\n\t// if (lastSelectedNode && !isAutoAdd) {\n\t// \tawait this.$nextTick();\n\t//\n\t// \tif (lastSelectedConnection?.__meta) {\n\t// \t\tthis.__deleteJSPlumbConnection(lastSelectedConnection, trackHistory);\n\t//\n\t// \t\tconst targetNodeName = lastSelectedConnection.__meta.targetNodeName;\n\t// \t\tconst targetOutputIndex = lastSelectedConnection.__meta.targetOutputIndex;\n\t// \t\tthis.connectTwoNodes(\n\t// \t\t\tnewNodeData.name,\n\t// \t\t\t0,\n\t// \t\t\ttargetNodeName,\n\t// \t\t\ttargetOutputIndex,\n\t// \t\t\tNodeConnectionType.Main,\n\t// \t\t);\n\t// \t}\n\t//\n\t// \t// Connect active node to the newly created one\n\t// \tthis.connectTwoNodes(\n\t// \t\tlastSelectedNode.name,\n\t// \t\toutputIndex,\n\t// \t\tnewNodeData.name,\n\t// \t\t0,\n\t// \t\tNodeConnectionType.Main,\n\t// \t);\n\t// }\n\t// this.historyStore.stopRecordingUndo();\n\n\treturn newNodeData;\n}\n\nasync function createNodeWithDefaultCredentials(node: Partial<INodeUi>) {\n\tconst nodeTypeDescription = nodeTypesStore.getNodeType(\n\t\tnode.type as string,\n\t) as INodeTypeDescription;\n\n\tlet nodeVersion = nodeTypeDescription.defaultVersion;\n\tif (nodeVersion === undefined) {\n\t\tnodeVersion = Array.isArray(nodeTypeDescription.version)\n\t\t\t? nodeTypeDescription.version.slice(-1)[0]\n\t\t\t: nodeTypeDescription.version;\n\t}\n\n\tconst newNodeData: INodeUi = {\n\t\tid: uuid(),\n\t\tname: node.name ?? (nodeTypeDescription.defaults.name as string),\n\t\ttype: nodeTypeDescription.name,\n\t\ttypeVersion: nodeVersion,\n\t\tposition: node.position ?? [0, 0],\n\t\tparameters: {},\n\t};\n\n\t/**\n\t * @TODO Implement this\n\t */\n\n\t// // Load the default parameter values because only values which differ\n\t// // from the defaults get saved\n\t// if (nodeType !== null) {\n\t// \tlet nodeParameters = null;\n\t// \ttry {\n\t// \t\tnodeParameters = NodeHelpers.getNodeParameters(\n\t// \t\t\tnodeType.properties,\n\t// \t\t\tnode.parameters,\n\t// \t\t\ttrue,\n\t// \t\t\tfalse,\n\t// \t\t\tnode,\n\t// \t\t);\n\t// \t} catch (e) {\n\t// \t\tconsole.error(\n\t// \t\t\tthis.$locale.baseText('nodeView.thereWasAProblemLoadingTheNodeParametersOfNode') +\n\t// \t\t\t`: \"${node.name}\"`,\n\t// \t\t);\n\t// \t\tconsole.error(e);\n\t// \t}\n\t// \tnode.parameters = nodeParameters !== null ? nodeParameters : {};\n\t//\n\t// \t// if it's a webhook and the path is empty set the UUID as the default path\n\t// \tif (\n\t// \t\t[WEBHOOK_NODE_TYPE, FORM_TRIGGER_NODE_TYPE].includes(node.type) &&\n\t// \t\tnode.parameters.path === ''\n\t// \t) {\n\t// \t\tnode.parameters.path = node.webhookId as string;\n\t// \t}\n\t// }\n\t// const credentialPerType = nodeTypeData.credentials\n\t// \t?.map((type) => credentialsStore.getUsableCredentialByType(type.name))\n\t// \t.flat();\n\t//\n\t// if (credentialPerType && credentialPerType.length === 1) {\n\t// \tconst defaultCredential = credentialPerType[0];\n\t//\n\t// \tconst selectedCredentials = credentialsStore.getCredentialById(defaultCredential.id);\n\t// \tconst selected = { id: selectedCredentials.id, name: selectedCredentials.name };\n\t// \tconst credentials = {\n\t// \t\t[defaultCredential.type]: selected,\n\t// \t};\n\t//\n\t// \tawait loadNodesProperties(\n\t// \t\t[newNodeData].map((node) => ({ name: node.type, version: node.typeVersion })),\n\t// \t);\n\t//\n\t// \tconst nodeType = nodeTypesStore.getNodeType(newNodeData.type, newNodeData.typeVersion);\n\t// \tconst nodeParameters = NodeHelpers.getNodeParameters(\n\t// \t\tnodeType?.properties ?? [],\n\t// \t\t{},\n\t// \t\ttrue,\n\t// \t\tfalse,\n\t// \t\tnewNodeData,\n\t// \t);\n\t//\n\t// \tif (nodeTypeData.credentials) {\n\t// \t\tconst authentication = nodeTypeData.credentials.find(\n\t// \t\t\t(type) => type.name === defaultCredential.type,\n\t// \t\t);\n\t// \t\tif (authentication?.displayOptions?.hide) {\n\t// \t\t\treturn newNodeData;\n\t// \t\t}\n\t//\n\t// \t\tconst authDisplayOptions = authentication?.displayOptions?.show;\n\t// \t\tif (!authDisplayOptions) {\n\t// \t\t\tnewNodeData.credentials = credentials;\n\t// \t\t\treturn newNodeData;\n\t// \t\t}\n\t//\n\t// \t\tif (Object.keys(authDisplayOptions).length === 1 && authDisplayOptions.authentication) {\n\t// \t\t\t// ignore complex case when there's multiple dependencies\n\t// \t\t\tnewNodeData.credentials = credentials;\n\t//\n\t// \t\t\tlet parameters: { [key: string]: string } = {};\n\t// \t\t\tfor (const displayOption of Object.keys(authDisplayOptions)) {\n\t// \t\t\t\tif (nodeParameters && !nodeParameters[displayOption]) {\n\t// \t\t\t\t\tparameters = {};\n\t// \t\t\t\t\tnewNodeData.credentials = undefined;\n\t// \t\t\t\t\tbreak;\n\t// \t\t\t\t}\n\t// \t\t\t\tconst optionValue = authDisplayOptions[displayOption]?.[0];\n\t// \t\t\t\tif (optionValue && typeof optionValue === 'string') {\n\t// \t\t\t\t\tparameters[displayOption] = optionValue;\n\t// \t\t\t\t}\n\t// \t\t\t\tnewNodeData.parameters = {\n\t// \t\t\t\t\t...newNodeData.parameters,\n\t// \t\t\t\t\t...parameters,\n\t// \t\t\t\t};\n\t// \t\t\t}\n\t// \t\t}\n\t// \t}\n\t// }\n\n\treturn newNodeData;\n}\n\n/**\n * @TODO Implement if needed\n */\n// async loadNodesProperties(nodeInfos: INodeTypeNameVersion[]): Promise<void> {\n// \tconst allNodes: INodeTypeDescription[] = this.nodeTypesStore.allNodeTypes;\n//\n// const nodesToBeFetched: INodeTypeNameVersion[] = [];\n// allNodes.forEach((node) => {\n// \tconst nodeVersions = Array.isArray(node.version) ? node.version : [node.version];\n// \tif (\n// \t\t!!nodeInfos.find((n) => n.name === node.name && nodeVersions.includes(n.version)) &&\n// \t\t!node.hasOwnProperty('properties')\n// \t) {\n// \t\tnodesToBeFetched.push({\n// \t\t\tname: node.name,\n// \t\t\tversion: Array.isArray(node.version) ? node.version.slice(-1)[0] : node.version,\n// \t\t});\n// \t}\n// });\n//\n// if (nodesToBeFetched.length > 0) {\n// \t// Only call API if node information is actually missing\n// \tthis.canvasStore.startLoading();\n// \tawait this.nodeTypesStore.getNodesInformation(nodesToBeFetched);\n// \tthis.canvasStore.stopLoading();\n// }\n// }\n\n/**\n * @TODO Probably not needed and can be merged into addNode\n */\nasync function injectNode(\n\tnodeTypeName: string,\n\toptions: AddNodeOptions = {},\n\tshowDetail = true,\n\ttrackHistory = false,\n\tisAutoAdd = false,\n) {\n\t// const nodeTypeData: INodeTypeDescription | null =\n\t// \tthis.nodeTypesStore.getNodeType(nodeTypeName);\n\t//\n\t// if (nodeTypeData === null) {\n\t// \tthis.showMessage({\n\t// \t\ttitle: this.$locale.baseText('nodeView.showMessage.addNodeButton.title'),\n\t// \t\tmessage: this.$locale.baseText('nodeView.showMessage.addNodeButton.message', {\n\t// \t\t\tinterpolate: { nodeTypeName },\n\t// \t\t}),\n\t// \t\ttype: 'error',\n\t// \t});\n\t// \treturn;\n\t// }\n\t//\n\t// if (\n\t// \tnodeTypeData.maxNodes !== undefined &&\n\t// \tthis.workflowHelpers.getNodeTypeCount(nodeTypeName) >= nodeTypeData.maxNodes\n\t// ) {\n\t// \tthis.showMaxNodeTypeError(nodeTypeData);\n\t// \treturn;\n\t// }\n\t//\n\t// const newNodeData = await this.getNewNodeWithDefaultCredential(nodeTypeData, {\n\t// \tname: options.name,\n\t// });\n\t//\n\t// // when pulling new connection from node or injecting into a connection\n\t// const lastSelectedNode = this.lastSelectedNode;\n\t//\n\t// if (options.position) {\n\t// \tnewNodeData.position = NodeViewUtils.getNewNodePosition(\n\t// \t\tthis.canvasStore.getNodesWithPlaceholderNode(),\n\t// \t\toptions.position,\n\t// \t);\n\t// } else if (lastSelectedNode) {\n\t// \tconst lastSelectedConnection = this.canvasStore.lastSelectedConnection;\n\t// \tif (lastSelectedConnection) {\n\t// \t\t// set when injecting into a connection\n\t// \t\tconst [diffX] = NodeViewUtils.getConnectorLengths(lastSelectedConnection);\n\t// \t\tif (diffX <= NodeViewUtils.MAX_X_TO_PUSH_DOWNSTREAM_NODES) {\n\t// \t\t\tthis.pushDownstreamNodes(\n\t// \t\t\t\tlastSelectedNode.name,\n\t// \t\t\t\tNodeViewUtils.PUSH_NODES_OFFSET,\n\t// \t\t\t\ttrackHistory,\n\t// \t\t\t);\n\t// \t\t}\n\t// \t}\n\t//\n\t// \t// set when pulling connections\n\t// \tif (this.canvasStore.newNodeInsertPosition) {\n\t// \t\tnewNodeData.position = NodeViewUtils.getNewNodePosition(this.nodes, [\n\t// \t\t\tthis.canvasStore.newNodeInsertPosition[0] + NodeViewUtils.GRID_SIZE,\n\t// \t\t\tthis.canvasStore.newNodeInsertPosition[1] - NodeViewUtils.NODE_SIZE / 2,\n\t// \t\t]);\n\t// \t\tthis.canvasStore.newNodeInsertPosition = null;\n\t// \t} else {\n\t// \t\tlet yOffset = 0;\n\t// \t\tconst workflow = this.workflowHelpers.getCurrentWorkflow();\n\t//\n\t// \t\tif (lastSelectedConnection) {\n\t// \t\t\tconst sourceNodeType = this.nodeTypesStore.getNodeType(\n\t// \t\t\t\tlastSelectedNode.type,\n\t// \t\t\t\tlastSelectedNode.typeVersion,\n\t// \t\t\t);\n\t//\n\t// \t\t\tif (sourceNodeType) {\n\t// \t\t\t\tconst offsets = [\n\t// \t\t\t\t\t[-100, 100],\n\t// \t\t\t\t\t[-140, 0, 140],\n\t// \t\t\t\t\t[-240, -100, 100, 240],\n\t// \t\t\t\t];\n\t//\n\t// \t\t\t\tconst sourceNodeOutputs = NodeHelpers.getNodeOutputs(\n\t// \t\t\t\t\tworkflow,\n\t// \t\t\t\t\tlastSelectedNode,\n\t// \t\t\t\t\tsourceNodeType,\n\t// \t\t\t\t);\n\t// \t\t\t\tconst sourceNodeOutputTypes = NodeHelpers.getConnectionTypes(sourceNodeOutputs);\n\t//\n\t// \t\t\t\tconst sourceNodeOutputMainOutputs = sourceNodeOutputTypes.filter(\n\t// \t\t\t\t\t(output) => output === NodeConnectionType.Main,\n\t// \t\t\t\t);\n\t//\n\t// \t\t\t\tif (sourceNodeOutputMainOutputs.length > 1) {\n\t// \t\t\t\t\tconst offset = offsets[sourceNodeOutputMainOutputs.length - 2];\n\t// \t\t\t\t\tconst sourceOutputIndex = lastSelectedConnection.__meta\n\t// \t\t\t\t\t\t? lastSelectedConnection.__meta.sourceOutputIndex\n\t// \t\t\t\t\t\t: 0;\n\t// \t\t\t\t\tyOffset = offset[sourceOutputIndex];\n\t// \t\t\t\t}\n\t// \t\t\t}\n\t// \t\t}\n\t//\n\t// \t\tlet outputs: Array<ConnectionTypes | INodeOutputConfiguration> = [];\n\t// \t\ttry {\n\t// \t\t\t// It fails when the outputs are an expression. As those nodes have\n\t// \t\t\t// normally no outputs by default and the only reason we need the\n\t// \t\t\t// outputs here is to calculate the position, it is fine to assume\n\t// \t\t\t// that they have no outputs and are so treated as a regular node\n\t// \t\t\t// with only \"main\" outputs.\n\t// \t\t\toutputs = NodeHelpers.getNodeOutputs(workflow, newNodeData, nodeTypeData);\n\t// \t\t} catch (e) {}\n\t// \t\tconst outputTypes = NodeHelpers.getConnectionTypes(outputs);\n\t// \t\tconst lastSelectedNodeType = this.nodeTypesStore.getNodeType(\n\t// \t\t\tlastSelectedNode.type,\n\t// \t\t\tlastSelectedNode.typeVersion,\n\t// \t\t);\n\t//\n\t// \t\t// If node has only scoped outputs, position it below the last selected node\n\t// \t\tif (\n\t// \t\t\toutputTypes.length > 0 &&\n\t// \t\t\toutputTypes.every((outputName) => outputName !== NodeConnectionType.Main)\n\t// \t\t) {\n\t// \t\t\tconst lastSelectedNodeWorkflow = workflow.getNode(lastSelectedNode.name);\n\t// \t\t\tconst lastSelectedInputs = NodeHelpers.getNodeInputs(\n\t// \t\t\t\tworkflow,\n\t// \t\t\t\tlastSelectedNodeWorkflow,\n\t// \t\t\t\tlastSelectedNodeType,\n\t// \t\t\t);\n\t// \t\t\tconst lastSelectedInputTypes = NodeHelpers.getConnectionTypes(lastSelectedInputs);\n\t//\n\t// \t\t\tconst scopedConnectionIndex = (lastSelectedInputTypes || [])\n\t// \t\t\t\t.filter((input) => input !== NodeConnectionType.Main)\n\t// \t\t\t\t.findIndex((inputType) => outputs[0] === inputType);\n\t//\n\t// \t\t\tnewNodeData.position = NodeViewUtils.getNewNodePosition(\n\t// \t\t\t\tthis.nodes,\n\t// \t\t\t\t[\n\t// \t\t\t\t\tlastSelectedNode.position[0] +\n\t// \t\t\t\t\t(NodeViewUtils.NODE_SIZE /\n\t// \t\t\t\t\t\t(Math.max(lastSelectedNodeType?.inputs?.length ?? 1), 1)) *\n\t// \t\t\t\t\tscopedConnectionIndex,\n\t// \t\t\t\t\tlastSelectedNode.position[1] + NodeViewUtils.PUSH_NODES_OFFSET,\n\t// \t\t\t\t],\n\t// \t\t\t\t[100, 0],\n\t// \t\t\t);\n\t// \t\t} else {\n\t// \t\t\t// Has only main outputs or no outputs at all\n\t// \t\t\tconst inputs = NodeHelpers.getNodeInputs(\n\t// \t\t\t\tworkflow,\n\t// \t\t\t\tlastSelectedNode,\n\t// \t\t\t\tlastSelectedNodeType,\n\t// \t\t\t);\n\t// \t\t\tconst inputsTypes = NodeHelpers.getConnectionTypes(inputs);\n\t//\n\t// \t\t\tlet pushOffset = NodeViewUtils.PUSH_NODES_OFFSET;\n\t// \t\t\tif (!!inputsTypes.find((input) => input !== NodeConnectionType.Main)) {\n\t// \t\t\t\t// If the node has scoped inputs, push it down a bit more\n\t// \t\t\t\tpushOffset += 150;\n\t// \t\t\t}\n\t//\n\t// \t\t\t// If a node is active then add the new node directly after the current one\n\t// \t\t\tnewNodeData.position = NodeViewUtils.getNewNodePosition(\n\t// \t\t\t\tthis.nodes,\n\t// \t\t\t\t[lastSelectedNode.position[0] + pushOffset, lastSelectedNode.position[1] + yOffset],\n\t// \t\t\t\t[100, 0],\n\t// \t\t\t);\n\t// \t\t}\n\t// \t}\n\t// } else {\n\t// \t// If added node is a trigger and it's the first one added to the canvas\n\t// \t// we place it at canvasAddButtonPosition to replace the canvas add button\n\t// \tconst position =\n\t// \t\tthis.nodeTypesStore.isTriggerNode(nodeTypeName) && !this.containsTrigger\n\t// \t\t\t? this.canvasStore.canvasAddButtonPosition\n\t// \t\t\t: // If no node is active find a free spot\n\t// \t\t\t(this.lastClickPosition as XYPosition);\n\t//\n\t// \tnewNodeData.position = NodeViewUtils.getNewNodePosition(this.nodes, position);\n\t// }\n\t//\n\t// const localizedName = this.locale.localizeNodeName(newNodeData.name, newNodeData.type);\n\t//\n\t// newNodeData.name = this.uniqueNodeName(localizedName);\n\t//\n\t// if (nodeTypeData.webhooks?.length) {\n\t// \tnewNodeData.webhookId = uuid();\n\t// }\n\t//\n\t// await this.addNodes([newNodeData], undefined, trackHistory);\n\t// this.workflowsStore.setNodePristine(newNodeData.name, true);\n\t//\n\t// this.uiStore.stateIsDirty = true;\n\t//\n\t// if (nodeTypeName === STICKY_NODE_TYPE) {\n\t// \tthis.$telemetry.trackNodesPanel('nodeView.addSticky', {\n\t// \t\tworkflow_id: this.workflowsStore.workflowId,\n\t// \t});\n\t// } else {\n\t// \tvoid this.externalHooks.run('nodeView.addNodeButton', { nodeTypeName });\n\t// \tuseSegment().trackAddedTrigger(nodeTypeName);\n\t// \tconst trackProperties: ITelemetryTrackProperties = {\n\t// \t\tnode_type: nodeTypeName,\n\t// \t\tnode_version: newNodeData.typeVersion,\n\t// \t\tis_auto_add: isAutoAdd,\n\t// \t\tworkflow_id: this.workflowsStore.workflowId,\n\t// \t\tdrag_and_drop: options.dragAndDrop,\n\t// \t};\n\t//\n\t// \tif (lastSelectedNode) {\n\t// \t\ttrackProperties.input_node_type = lastSelectedNode.type;\n\t// \t}\n\t//\n\t// \tthis.$telemetry.trackNodesPanel('nodeView.addNodeButton', trackProperties);\n\t// }\n\t//\n\t// // Automatically deselect all nodes and select the current one and also active\n\t// // current node. But only if it's added manually by the user (not by undo/redo mechanism)\n\t// if (trackHistory) {\n\t// \tthis.deselectAllNodes();\n\t// \tsetTimeout(() => {\n\t// \t\tthis.nodeSelectedByName(\n\t// \t\t\tnewNodeData.name,\n\t// \t\t\tshowDetail && nodeTypeName !== STICKY_NODE_TYPE,\n\t// \t\t);\n\t// \t});\n\t// }\n\t//\n\t// return newNodeData;\n}\n\nfunction checkIfEditingIsAllowed(): boolean {\n\tif (readOnlyNotification.value?.visible) {\n\t\treturn false;\n\t}\n\n\tif (isReadOnlyRoute.value || isReadOnlyEnvironment.value) {\n\t\tconst messageContext = isReadOnlyRoute.value ? 'executions' : 'workflows';\n\t\treadOnlyNotification.value = toast.showMessage({\n\t\t\ttitle: i18n.baseText(\n\t\t\t\tisReadOnlyEnvironment.value\n\t\t\t\t\t? `readOnlyEnv.showMessage.${messageContext}.title`\n\t\t\t\t\t: 'readOnly.showMessage.executions.title',\n\t\t\t),\n\t\t\tmessage: i18n.baseText(\n\t\t\t\tisReadOnlyEnvironment.value\n\t\t\t\t\t? `readOnlyEnv.showMessage.${messageContext}.message`\n\t\t\t\t\t: 'readOnly.showMessage.executions.message',\n\t\t\t),\n\t\t\ttype: 'info',\n\t\t\tdangerouslyUseHTMLString: true,\n\t\t}) as unknown as { visible: boolean };\n\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n</script>\n\n<template>\n\t<WorkflowCanvas\n\t\tv-if=\"editableWorkflow && editableWorkflowObject\"\n\t\t:workflow=\"editableWorkflow\"\n\t\t:workflow-object=\"editableWorkflowObject\"\n\t\t@update:node:position=\"onNodePositionUpdate\"\n\t\t@create:connection=\"onCreateNodeConnection\"\n\t>\n\t\t<div :class=\"$style.executionButtons\">\n\t\t\t<CanvasExecuteWorkflowButton @click=\"onRunWorkflow\" />\n\t\t</div>\n\t\t<Suspense>\n\t\t\t<NodeCreation\n\t\t\t\tv-if=\"!isReadOnlyRoute && !isReadOnlyEnvironment\"\n\t\t\t\t:create-node-active=\"uiStore.isCreateNodeActive\"\n\t\t\t\t:node-view-scale=\"1\"\n\t\t\t\t@toggle-node-creator=\"onToggleNodeCreator\"\n\t\t\t\t@add-nodes=\"onAddNodes\"\n\t\t\t/>\n\t\t</Suspense>\n\t</WorkflowCanvas>\n</template>\n\n<style lang=\"scss\" module>\n.executionButtons {\n\tposition: absolute;\n\tdisplay: flex;\n\tjustify-content: center;\n\talign-items: center;\n\tleft: 50%;\n\ttransform: translateX(-50%);\n\tbottom: var(--spacing-l);\n\twidth: auto;\n\n\t@media (max-width: $breakpoint-2xs) {\n\t\tbottom: 150px;\n\t}\n\n\tbutton {\n\t\tdisplay: flex;\n\t\tjustify-content: center;\n\t\talign-items: center;\n\t\tmargin-left: 0.625rem;\n\n\t\t&:first-child {\n\t\t\tmargin: 0;\n\t\t}\n\t}\n}\n</style>\n"],"file":"assets/NodeView.v2-DnTCsiDE.js"}
@@ -1,2 +1,2 @@
1
- import{e2 as h,cf as c,w as j}from"./index-CY2ZfL2U.js";import{G as P,e as n,ag as l,l as m,M as u,O as f,S as g,T as x,R as i}from"./vendor-CUQSof8H.js";const T=P({__name:"ProjectCardBadge",props:{resource:{},personalProject:{}},setup(p){const e=p,d=j(),s=n(()=>{var o;if(e.resource.homeProject&&e.personalProject&&e.resource.homeProject.id===e.personalProject.id||!e.resource.homeProject)return d.baseText("generic.ownedByMe");{const{firstName:t,lastName:r}=h(((o=e.resource.homeProject)==null?void 0:o.name)??"");return`${t}${r?" "+r:""}`}}),a=n(()=>{var o,t,r;return(o=e.resource.sharedWithProjects)!=null&&o.length&&((t=e.resource.homeProject)==null?void 0:t.type)!==c.Team?"user-friends":((r=e.resource.homeProject)==null?void 0:r.type)===c.Team?"archive":""});return(o,t)=>{const r=l("n8n-icon"),_=l("n8n-badge");return s.value?(m(),u(_,{key:0,class:"mr-xs",theme:"tertiary",bold:"","data-test-id":"card-badge"},{default:f(()=>[g(x(s.value)+" ",1),a.value?(m(),u(r,{key:0,icon:a.value,size:"small",class:"ml-5xs"},null,8,["icon"])):i("",!0)]),_:1})):i("",!0)}}});export{T as _};
2
- //# sourceMappingURL=ProjectCardBadge.vue_vue_type_script_setup_true_lang-BRGRmswR.js.map
1
+ import{e2 as h,cf as c,w as j}from"./index-BQ6Z7VRj.js";import{G as P,e as n,ag as l,l as m,M as u,O as f,S as g,T as x,R as i}from"./vendor-CUQSof8H.js";const T=P({__name:"ProjectCardBadge",props:{resource:{},personalProject:{}},setup(p){const e=p,d=j(),s=n(()=>{var o;if(e.resource.homeProject&&e.personalProject&&e.resource.homeProject.id===e.personalProject.id||!e.resource.homeProject)return d.baseText("generic.ownedByMe");{const{firstName:t,lastName:r}=h(((o=e.resource.homeProject)==null?void 0:o.name)??"");return`${t}${r?" "+r:""}`}}),a=n(()=>{var o,t,r;return(o=e.resource.sharedWithProjects)!=null&&o.length&&((t=e.resource.homeProject)==null?void 0:t.type)!==c.Team?"user-friends":((r=e.resource.homeProject)==null?void 0:r.type)===c.Team?"archive":""});return(o,t)=>{const r=l("n8n-icon"),_=l("n8n-badge");return s.value?(m(),u(_,{key:0,class:"mr-xs",theme:"tertiary",bold:"","data-test-id":"card-badge"},{default:f(()=>[g(x(s.value)+" ",1),a.value?(m(),u(r,{key:0,icon:a.value,size:"small",class:"ml-5xs"},null,8,["icon"])):i("",!0)]),_:1})):i("",!0)}}});export{T as _};
2
+ //# sourceMappingURL=ProjectCardBadge.vue_vue_type_script_setup_true_lang-CYFr8_zj.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ProjectCardBadge.vue_vue_type_script_setup_true_lang-BRGRmswR.js","sources":["../../src/features/projects/components/ProjectCardBadge.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport { computed } from 'vue';\nimport { useI18n } from '@/composables/useI18n';\nimport { ProjectTypes, splitName } from '@/features/projects/projects.utils';\nimport type { ICredentialsResponse, IWorkflowDb } from '@/Interface';\nimport type { Project } from '@/features/projects/projects.types';\n\ntype Props = {\n\tresource: IWorkflowDb | ICredentialsResponse;\n\tpersonalProject: Project | null;\n};\n\nconst props = defineProps<Props>();\n\nconst locale = useI18n();\n\nconst badgeText = computed(() => {\n\tif (\n\t\t(props.resource.homeProject &&\n\t\t\tprops.personalProject &&\n\t\t\tprops.resource.homeProject.id === props.personalProject.id) ||\n\t\t!props.resource.homeProject\n\t) {\n\t\treturn locale.baseText('generic.ownedByMe');\n\t} else {\n\t\tconst { firstName, lastName } = splitName(props.resource.homeProject?.name ?? '');\n\t\treturn `${firstName}${lastName ? ' ' + lastName : ''}`;\n\t}\n});\n\nconst badgeIcon = computed(() => {\n\tif (\n\t\tprops.resource.sharedWithProjects?.length &&\n\t\tprops.resource.homeProject?.type !== ProjectTypes.Team\n\t) {\n\t\treturn 'user-friends';\n\t} else if (props.resource.homeProject?.type === ProjectTypes.Team) {\n\t\treturn 'archive';\n\t} else {\n\t\treturn '';\n\t}\n});\n</script>\n<template>\n\t<n8n-badge v-if=\"badgeText\" class=\"mr-xs\" theme=\"tertiary\" bold data-test-id=\"card-badge\">\n\t\t{{ badgeText }}\n\t\t<n8n-icon v-if=\"badgeIcon\" :icon=\"badgeIcon\" size=\"small\" class=\"ml-5xs\" />\n\t</n8n-badge>\n</template>\n\n<style lang=\"scss\" module></style>\n"],"names":["props","__props","locale","useI18n","badgeText","computed","firstName","lastName","splitName","_a","badgeIcon","_b","ProjectTypes","_c"],"mappings":"+OAYA,MAAMA,EAAQC,EAERC,EAASC,IAETC,EAAYC,EAAS,IAAM,OAChC,GACEL,EAAM,SAAS,aACfA,EAAM,iBACNA,EAAM,SAAS,YAAY,KAAOA,EAAM,gBAAgB,IACzD,CAACA,EAAM,SAAS,YAET,OAAAE,EAAO,SAAS,mBAAmB,EACpC,CACA,KAAA,CAAE,UAAAI,EAAW,SAAAC,CAAS,EAAIC,IAAUC,EAAAT,EAAM,SAAS,cAAf,YAAAS,EAA4B,OAAQ,EAAE,EAChF,MAAO,GAAGH,CAAS,GAAGC,EAAW,IAAMA,EAAW,EAAE,EACrD,CAAA,CACA,EAEKG,EAAYL,EAAS,IAAM,WAE/B,OAAAI,EAAAT,EAAM,SAAS,qBAAf,MAAAS,EAAmC,UACnCE,EAAAX,EAAM,SAAS,cAAf,YAAAW,EAA4B,QAASC,EAAa,KAE3C,iBACGC,EAAAb,EAAM,SAAS,cAAf,YAAAa,EAA4B,QAASD,EAAa,KACrD,UAEA,EACR,CACA"}
1
+ {"version":3,"file":"ProjectCardBadge.vue_vue_type_script_setup_true_lang-CYFr8_zj.js","sources":["../../src/features/projects/components/ProjectCardBadge.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport { computed } from 'vue';\nimport { useI18n } from '@/composables/useI18n';\nimport { ProjectTypes, splitName } from '@/features/projects/projects.utils';\nimport type { ICredentialsResponse, IWorkflowDb } from '@/Interface';\nimport type { Project } from '@/features/projects/projects.types';\n\ntype Props = {\n\tresource: IWorkflowDb | ICredentialsResponse;\n\tpersonalProject: Project | null;\n};\n\nconst props = defineProps<Props>();\n\nconst locale = useI18n();\n\nconst badgeText = computed(() => {\n\tif (\n\t\t(props.resource.homeProject &&\n\t\t\tprops.personalProject &&\n\t\t\tprops.resource.homeProject.id === props.personalProject.id) ||\n\t\t!props.resource.homeProject\n\t) {\n\t\treturn locale.baseText('generic.ownedByMe');\n\t} else {\n\t\tconst { firstName, lastName } = splitName(props.resource.homeProject?.name ?? '');\n\t\treturn `${firstName}${lastName ? ' ' + lastName : ''}`;\n\t}\n});\n\nconst badgeIcon = computed(() => {\n\tif (\n\t\tprops.resource.sharedWithProjects?.length &&\n\t\tprops.resource.homeProject?.type !== ProjectTypes.Team\n\t) {\n\t\treturn 'user-friends';\n\t} else if (props.resource.homeProject?.type === ProjectTypes.Team) {\n\t\treturn 'archive';\n\t} else {\n\t\treturn '';\n\t}\n});\n</script>\n<template>\n\t<n8n-badge v-if=\"badgeText\" class=\"mr-xs\" theme=\"tertiary\" bold data-test-id=\"card-badge\">\n\t\t{{ badgeText }}\n\t\t<n8n-icon v-if=\"badgeIcon\" :icon=\"badgeIcon\" size=\"small\" class=\"ml-5xs\" />\n\t</n8n-badge>\n</template>\n\n<style lang=\"scss\" module></style>\n"],"names":["props","__props","locale","useI18n","badgeText","computed","firstName","lastName","splitName","_a","badgeIcon","_b","ProjectTypes","_c"],"mappings":"+OAYA,MAAMA,EAAQC,EAERC,EAASC,IAETC,EAAYC,EAAS,IAAM,OAChC,GACEL,EAAM,SAAS,aACfA,EAAM,iBACNA,EAAM,SAAS,YAAY,KAAOA,EAAM,gBAAgB,IACzD,CAACA,EAAM,SAAS,YAET,OAAAE,EAAO,SAAS,mBAAmB,EACpC,CACA,KAAA,CAAE,UAAAI,EAAW,SAAAC,CAAS,EAAIC,IAAUC,EAAAT,EAAM,SAAS,cAAf,YAAAS,EAA4B,OAAQ,EAAE,EAChF,MAAO,GAAGH,CAAS,GAAGC,EAAW,IAAMA,EAAW,EAAE,EACrD,CAAA,CACA,EAEKG,EAAYL,EAAS,IAAM,WAE/B,OAAAI,EAAAT,EAAM,SAAS,qBAAf,MAAAS,EAAmC,UACnCE,EAAAX,EAAM,SAAS,cAAf,YAAAW,EAA4B,QAASC,EAAa,KAE3C,iBACGC,EAAAb,EAAM,SAAS,cAAf,YAAAa,EAA4B,QAASD,EAAa,KACrD,UAEA,EACR,CACA"}
@@ -1,2 +1,2 @@
1
- import{G,aI as W,aJ as Z,r as V,e as B,l as h,M as H,O as i,U as l,S as b,T as u,u as r,a2 as L,p as m,m as D,I as S,R as F,ag as v,aH as ue,d as de,D as pe,F as me,a7 as ve,n as je}from"./vendor-CUQSof8H.js";import{_ as ee,h as Y}from"./n8n-DT_bOwuZ.js";import{dV as be,w as J,i as fe,a as ge,o as _e,e6 as ye,R as Pe,u as xe,V as Te,F as Ve}from"./index-CY2ZfL2U.js";import{P as he}from"./ProjectTabs-B_U7Q16t.js";import"./axios-Mm4CS0gO.js";import"./esprima-next-nhoSXAeq.js";import"./luxon-CLwAIbs0.js";import"./lodash-es-BFdF4Er8.js";import"./pinia-Dh4cxKZ0.js";import"./flatted-DN8lQ2XG.js";import"./@vueuse/core-BiGWdRh4.js";import"./@n8n/permissions-BxxteU-C.js";import"./dateformat-C0ZgbPvs.js";import"./vue-i18n-CG6eDDlD.js";import"./uuid-SoommWqA.js";import"./@n8n/codemirror-lang-sql-x14jMqbG.js";import"./@lezer/common-B6ct0j_v.js";import"./prettier-bS6l4Vb1.js";import"./@jsplumb/util-DS-9vq_E.js";import"./@jsplumb/core-CVBraiyY.js";import"./@jsplumb/common-CF-b-6-M.js";import"./@jsplumb/connector-bezier-BGU0Ovbw.js";import"./@jsplumb/browser-ui-BVF2KoJK.js";import"./codemirror-lang-html-n8n-DcTmlMkf.js";import"./@n8n/codemirror-lang-Qkdx7NoQ.js";import"./fast-json-stable-stringify-wY6jAr7b.js";import"./timeago.js-CiyKClrF.js";import"./qrcode.vue-DOxvr88t.js";import"./vue3-touch-events-mV0oX_Sl.js";import"./chart.js-343vZi4M.js";const Ne={class:"pt-l"},Ue=G({__name:"ProjectDeleteDialog",props:W({currentProject:{},projects:{}},{modelValue:{type:Boolean},modelModifiers:{}}),emits:W(["confirmDelete"],["update:modelValue"]),setup(M,{emit:f}){const n=M,o=Z(M,"modelValue"),N=f,j=J(),g=V(null),p=V(null),y=V(""),P=B(()=>p.value==="transfer"?!!g.value:p.value==="wipe"?y.value===j.baseText("projects.settings.delete.question.wipe.placeholder"):!1),U=()=>{var d;P.value&&(p.value==="wipe"&&(g.value=null),N("confirmDelete",(d=g.value)==null?void 0:d.id))};return(d,s)=>{var A;const $=v("n8n-text"),w=v("el-radio"),O=v("n8n-input"),z=v("n8n-input-label"),I=v("N8nButton"),R=v("el-dialog");return h(),H(R,{modelValue:o.value,"onUpdate:modelValue":s[4]||(s[4]=x=>o.value=x),title:r(j).baseText("projects.settings.delete.title",{interpolate:{projectName:((A=n.currentProject)==null?void 0:A.name)??""}}),width:"500"},{footer:i(()=>[l(I,{type:"danger","native-type":"button",disabled:!P.value,"data-test-id":"project-settings-delete-confirm-button",onClick:L(U,["stop","prevent"])},{default:i(()=>[b(u(r(j).baseText("projects.settings.danger.deleteProject")),1)]),_:1},8,["disabled"])]),default:i(()=>[l($,{color:"text-base"},{default:i(()=>[b(u(r(j).baseText("projects.settings.delete.message")),1)]),_:1}),m("div",Ne,[l(w,{"model-value":p.value,label:"transfer",class:"mb-s","onUpdate:modelValue":s[0]||(s[0]=x=>p.value="transfer")},{default:i(()=>[l($,{color:"text-dark"},{default:i(()=>[b(u(r(j).baseText("projects.settings.delete.question.transfer.label")),1)]),_:1})]),_:1},8,["model-value"]),p.value==="transfer"?(h(),D("div",{key:0,class:S(d.$style.operation)},[l($,{color:"text-dark"},{default:i(()=>[b(u(r(j).baseText("projects.settings.delete.question.transfer.title")),1)]),_:1}),l(be,{modelValue:g.value,"onUpdate:modelValue":s[1]||(s[1]=x=>g.value=x),class:"pt-2xs",projects:n.projects,"empty-options-text":r(j).baseText("projects.sharing.noMatchingProjects")},null,8,["modelValue","projects","empty-options-text"])],2)):F("",!0),l(w,{"model-value":p.value,label:"wipe",class:"mb-s","onUpdate:modelValue":s[2]||(s[2]=x=>p.value="wipe")},{default:i(()=>[l($,{color:"text-dark"},{default:i(()=>[b(u(r(j).baseText("projects.settings.delete.question.wipe.label")),1)]),_:1})]),_:1},8,["model-value"]),p.value==="wipe"?(h(),D("div",{key:1,class:S(d.$style.operation)},[l(z,{label:r(j).baseText("projects.settings.delete.question.wipe.title")},{default:i(()=>[l(O,{modelValue:y.value,"onUpdate:modelValue":s[3]||(s[3]=x=>y.value=x),placeholder:r(j).baseText("projects.settings.delete.question.wipe.placeholder")},null,8,["modelValue","placeholder"])]),_:1},8,["label"])],2)):F("",!0)])]),_:1},8,["modelValue","title"])}}}),we="_operation_1mn5e_1",ke={operation:we},Se={$style:ke},Me=ee(Ue,[["__cssModules",Se]]),$e={class:"pt-l"},Ce=G({__name:"ProjectRoleUpgradeDialog",props:W({limit:{},planName:{}},{modelValue:{type:Boolean},modelModifiers:{}}),emits:["update:modelValue"],setup(M){const f=M,n=Z(M,"modelValue"),o=fe(),N=J(),j=async()=>{await o.goToUpgrade("rbac","upgrade-rbac"),n.value=!1};return(g,p)=>{const y=v("i18n-t"),P=v("N8nButton"),U=v("el-dialog");return h(),H(U,{modelValue:n.value,"onUpdate:modelValue":p[1]||(p[1]=d=>n.value=d),title:r(N).baseText("projects.settings.role.upgrade.title"),width:"500"},{footer:i(()=>[l(P,{type:"secondary","native-type":"button",onClick:p[0]||(p[0]=d=>n.value=!1)},{default:i(()=>[b(u(r(N).baseText("generic.cancel")),1)]),_:1}),l(P,{type:"primary","native-type":"button",onClick:j},{default:i(()=>[b(u(r(N).baseText("projects.create.limitReached.link")),1)]),_:1})]),default:i(()=>[m("div",$e,[l(y,{keypath:"projects.settings.role.upgrade.message"},{planName:i(()=>[b(u(f.planName),1)]),limit:i(()=>[b(u(r(N).baseText("projects.create.limit",{adjustToNumber:f.limit,interpolate:{num:String(f.limit)}})),1)]),_:1})])]),_:1},8,["modelValue","title"])}}}),De={for:"name"},Ie={for:"projectMembers"},Be={key:0,class:"mr-2xs"},Re=m("hr",{class:"mb-2xl"},null,-1),Ae={class:"mb-xs"},Ee=m("br",null,null,-1),qe=G({__name:"ProjectSettings",setup(M){const f=ge(),n=J(),o=_e(),N=ye(),j=Pe(),g=xe(),p=ue(),y=Ve(),P=V(!1),U=V(!1),d=V(!1),s=V({name:"",relations:[]}),$=V({"project:editor":n.baseText("projects.settings.role.editor"),"project:admin":n.baseText("projects.settings.role.admin")}),w=V(null),O=B(()=>f.allUsers.filter(e=>!(s.value.relations||[]).find(a=>a.id===e.id))),z=B(()=>o.teamProjects.filter(e=>e.id!==o.currentProjectId)),I=B(()=>N.processedProjectRoles.map(e=>({...e,name:$.value[e.role]}))),R=B(()=>{var e;return(e=I.value.find(t=>t.licensed))==null?void 0:e.role}),A=e=>{d.value=!0;const t=f.getUserById(e);if(!t)return;const{id:a,firstName:c,lastName:C,email:k}=t,E={id:a,firstName:c,lastName:C,email:k};R.value&&(E.role=R.value),s.value.relations.push(E)},x=(e,t)=>{d.value=!0;const a=s.value.relations.findIndex(c=>c.id===e.id);t==="remove"?s.value.relations.splice(a,1):s.value.relations[a].role=t},te=()=>{d.value=!0},oe=()=>{var e,t;s.value.relations=(e=o.currentProject)!=null&&e.relations?Y(o.currentProject.relations):[],s.value.name=((t=o.currentProject)==null?void 0:t.name)??"",d.value=!1},se=()=>{const e={};return o.currentProject&&(s.value.name!==o.currentProject.name&&(e.name=s.value.name??""),s.value.relations.length!==o.currentProject.relations.length&&(e.memberAdded=s.value.relations.filter(t=>{var a;return!((a=o.currentProject)!=null&&a.relations.find(c=>c.id===t.id))}),e.memberRemoved=o.currentProject.relations.filter(t=>!s.value.relations.find(a=>a.id===t.id))),e.role=s.value.relations.filter(t=>{var c,C;const a=(c=o.currentProject)==null?void 0:c.relations.find(k=>k.id===t.id);return(a==null?void 0:a.role)!==t.role&&!((C=e.memberAdded)!=null&&C.find(k=>k.id===t.id))})),e},ae=e=>{var t;e.name&&y.track("User changed project name",{project_id:(t=o.currentProject)==null?void 0:t.id,name:e.name}),e.memberAdded&&e.memberAdded.forEach(a=>{var c;y.track("User added member to project",{project_id:(c=o.currentProject)==null?void 0:c.id,target_user_id:a.id,role:a.role})}),e.memberRemoved&&e.memberRemoved.forEach(a=>{var c;y.track("User removed member from project",{project_id:(c=o.currentProject)==null?void 0:c.id,target_user_id:a.id})}),e.role&&e.role.forEach(a=>{var c;y.track("User changed member role on project",{project_id:(c=o.currentProject)==null?void 0:c.id,target_user_id:a.id,role:a.role})})},re=async()=>{try{if(d.value&&o.currentProject){const e=se();await o.updateProject({id:o.currentProject.id,name:s.value.name,relations:s.value.relations.map(t=>({userId:t.id,role:t.role}))}),ae(e),d.value=!1,g.showMessage({title:n.baseText("projects.settings.save.successful.title",{interpolate:{projectName:s.value.name??""}}),type:"success"})}}catch(e){g.showError(e,n.baseText("projects.settings.save.error.title"))}},le=async()=>{await o.getAllProjects(),P.value=!0},ne=async e=>{var t;try{if(o.currentProject){const a=((t=o.currentProject)==null?void 0:t.name)??"";await o.deleteProject(o.currentProject.id,e),await p.push({name:Te.HOMEPAGE}),g.showMessage({title:n.baseText("projects.settings.delete.successful.title",{interpolate:{projectName:a}}),type:"success"}),P.value=!0}}catch(a){g.showError(a,n.baseText("projects.settings.delete.error.title"))}},ie=()=>{w.value&&s.value.name===n.baseText("projects.settings.newProjectName")&&(w.value.focus(),w.value.select())};return de(()=>o.currentProject,async()=>{var e,t;s.value.name=((e=o.currentProject)==null?void 0:e.name)??"",s.value.relations=(t=o.currentProject)!=null&&t.relations?Y(o.currentProject.relations):[],await je(),ie()},{immediate:!0}),pe(async()=>{await f.fetchUsers()}),(e,t)=>{var K,Q,X;const a=v("N8nInput"),c=v("N8nIcon"),C=v("N8nUserSelect"),k=v("N8nOption"),E=v("N8nSelect"),q=v("N8nButton"),ce=v("N8nUsersList");return h(),D("div",{class:S(e.$style.projectSettings)},[m("div",{class:S(e.$style.header)},[l(he)],2),m("form",{onSubmit:L(re,["prevent"])},[m("fieldset",null,[m("label",De,u(r(n).baseText("projects.settings.name")),1),l(a,{id:"name",ref_key:"nameInput",ref:w,modelValue:s.value.name,"onUpdate:modelValue":t[0]||(t[0]=_=>s.value.name=_),type:"text",name:"name",onInput:te},null,8,["modelValue"])]),m("fieldset",null,[m("label",Ie,u(r(n).baseText("projects.settings.projectMembers")),1),l(C,{id:"projectMembers",class:"mb-s",size:"large",users:O.value,"current-user-id":(K=r(f).currentUser)==null?void 0:K.id,placeholder:e.$locale.baseText("workflows.shareModal.select.placeholder"),"data-test-id":"project-members-select","onUpdate:modelValue":A},{prefix:i(()=>[l(c,{icon:"search"})]),_:1},8,["users","current-user-id","placeholder"]),l(ce,{actions:[],users:s.value.relations,"current-user-id":(Q=r(f).currentUser)==null?void 0:Q.id,"delete-label":e.$locale.baseText("workflows.shareModal.list.delete")},{actions:i(({user:_})=>[m("div",{class:S(e.$style.buttons)},[l(E,{class:"mr-2xs","model-value":(_==null?void 0:_.role)||I.value[0].role,size:"small","onUpdate:modelValue":T=>x(_,T)},{default:i(()=>[(h(!0),D(me,null,ve(I.value,T=>(h(),H(k,{key:T.role,value:T.role,label:T.name,disabled:!T.licensed},{default:i(()=>[b(u(T.name),1),T.licensed?F("",!0):(h(),D("span",{key:0,class:S(e.$style.upgrade),onClick:t[1]||(t[1]=He=>U.value=!0)},"  - "+u(r(n).baseText("generic.upgrade")),3))]),_:2},1032,["value","label","disabled"]))),128))]),_:2},1032,["model-value","onUpdate:modelValue"]),l(q,{type:"tertiary","native-type":"button",square:"",icon:"trash","data-test-id":"project-user-remove",onClick:T=>x(_,"remove")},null,8,["onClick"])],2)]),_:1},8,["users","current-user-id","delete-label"])]),m("fieldset",{class:S(e.$style.buttons)},[m("div",null,[d.value?(h(),D("small",Be,u(r(n).baseText("projects.settings.message.unsavedChanges")),1)):F("",!0),l(q,{disabled:!d.value,type:"secondary","native-type":"button",class:"mr-2xs","data-test-id":"project-settings-cancel-button",onClick:L(oe,["stop","prevent"])},{default:i(()=>[b(u(r(n).baseText("projects.settings.button.cancel")),1)]),_:1},8,["disabled"])]),l(q,{disabled:!d.value,type:"primary","data-test-id":"project-settings-save-button"},{default:i(()=>[b(u(r(n).baseText("projects.settings.button.save")),1)]),_:1},8,["disabled"])],2),m("fieldset",null,[Re,m("h3",Ae,u(r(n).baseText("projects.settings.danger.title")),1),m("small",null,u(r(n).baseText("projects.settings.danger.message")),1),Ee,l(q,{type:"tertiary","native-type":"button",class:"mt-s","data-test-id":"project-settings-delete-button",onClick:L(le,["stop","prevent"])},{default:i(()=>[b(u(r(n).baseText("projects.settings.danger.deleteProject")),1)]),_:1})])],32),l(Me,{modelValue:P.value,"onUpdate:modelValue":t[2]||(t[2]=_=>P.value=_),"current-project":r(o).currentProject,projects:z.value,onConfirmDelete:ne},null,8,["modelValue","current-project","projects"]),l(Ce,{modelValue:U.value,"onUpdate:modelValue":t[3]||(t[3]=_=>U.value=_),limit:r(o).teamProjectsLimit,"plan-name":(X=r(j).currentPlanData)==null?void 0:X.displayName},null,8,["modelValue","limit","plan-name"])],2)}}}),Le="_projectSettings_2vgb7_1",Fe="_header_2vgb7_21",Oe="_upgrade_2vgb7_27",ze="_buttons_2vgb7_31",We={projectSettings:Le,header:Fe,upgrade:Oe,buttons:ze},Ge={$style:We},Vt=ee(qe,[["__cssModules",Ge]]);export{Vt as default};
2
- //# sourceMappingURL=ProjectSettings-D3FAGvAm.js.map
1
+ import{G,aI as W,aJ as Z,r as V,e as B,l as h,M as H,O as i,U as l,S as b,T as u,u as r,a2 as L,p as m,m as D,I as S,R as F,ag as v,aH as ue,d as de,D as pe,F as me,a7 as ve,n as je}from"./vendor-CUQSof8H.js";import{_ as ee,h as Y}from"./n8n-DT_bOwuZ.js";import{dV as be,w as J,i as fe,a as ge,o as _e,e6 as ye,R as Pe,u as xe,V as Te,F as Ve}from"./index-BQ6Z7VRj.js";import{P as he}from"./ProjectTabs-1jmisSQb.js";import"./axios-Mm4CS0gO.js";import"./esprima-next-nhoSXAeq.js";import"./luxon-CLwAIbs0.js";import"./lodash-es-BFdF4Er8.js";import"./pinia-Dh4cxKZ0.js";import"./flatted-DN8lQ2XG.js";import"./@vueuse/core-BiGWdRh4.js";import"./@n8n/permissions-BxxteU-C.js";import"./dateformat-C0ZgbPvs.js";import"./vue-i18n-CG6eDDlD.js";import"./uuid-SoommWqA.js";import"./@n8n/codemirror-lang-sql-x14jMqbG.js";import"./@lezer/common-B6ct0j_v.js";import"./prettier-bS6l4Vb1.js";import"./@jsplumb/util-DS-9vq_E.js";import"./@jsplumb/core-CVBraiyY.js";import"./@jsplumb/common-CF-b-6-M.js";import"./@jsplumb/connector-bezier-BGU0Ovbw.js";import"./@jsplumb/browser-ui-BVF2KoJK.js";import"./codemirror-lang-html-n8n-DcTmlMkf.js";import"./@n8n/codemirror-lang-Qkdx7NoQ.js";import"./fast-json-stable-stringify-wY6jAr7b.js";import"./timeago.js-CiyKClrF.js";import"./qrcode.vue-DOxvr88t.js";import"./vue3-touch-events-mV0oX_Sl.js";import"./chart.js-343vZi4M.js";const Ne={class:"pt-l"},Ue=G({__name:"ProjectDeleteDialog",props:W({currentProject:{},projects:{}},{modelValue:{type:Boolean},modelModifiers:{}}),emits:W(["confirmDelete"],["update:modelValue"]),setup(M,{emit:f}){const n=M,o=Z(M,"modelValue"),N=f,j=J(),g=V(null),p=V(null),y=V(""),P=B(()=>p.value==="transfer"?!!g.value:p.value==="wipe"?y.value===j.baseText("projects.settings.delete.question.wipe.placeholder"):!1),U=()=>{var d;P.value&&(p.value==="wipe"&&(g.value=null),N("confirmDelete",(d=g.value)==null?void 0:d.id))};return(d,s)=>{var A;const $=v("n8n-text"),w=v("el-radio"),O=v("n8n-input"),z=v("n8n-input-label"),I=v("N8nButton"),R=v("el-dialog");return h(),H(R,{modelValue:o.value,"onUpdate:modelValue":s[4]||(s[4]=x=>o.value=x),title:r(j).baseText("projects.settings.delete.title",{interpolate:{projectName:((A=n.currentProject)==null?void 0:A.name)??""}}),width:"500"},{footer:i(()=>[l(I,{type:"danger","native-type":"button",disabled:!P.value,"data-test-id":"project-settings-delete-confirm-button",onClick:L(U,["stop","prevent"])},{default:i(()=>[b(u(r(j).baseText("projects.settings.danger.deleteProject")),1)]),_:1},8,["disabled"])]),default:i(()=>[l($,{color:"text-base"},{default:i(()=>[b(u(r(j).baseText("projects.settings.delete.message")),1)]),_:1}),m("div",Ne,[l(w,{"model-value":p.value,label:"transfer",class:"mb-s","onUpdate:modelValue":s[0]||(s[0]=x=>p.value="transfer")},{default:i(()=>[l($,{color:"text-dark"},{default:i(()=>[b(u(r(j).baseText("projects.settings.delete.question.transfer.label")),1)]),_:1})]),_:1},8,["model-value"]),p.value==="transfer"?(h(),D("div",{key:0,class:S(d.$style.operation)},[l($,{color:"text-dark"},{default:i(()=>[b(u(r(j).baseText("projects.settings.delete.question.transfer.title")),1)]),_:1}),l(be,{modelValue:g.value,"onUpdate:modelValue":s[1]||(s[1]=x=>g.value=x),class:"pt-2xs",projects:n.projects,"empty-options-text":r(j).baseText("projects.sharing.noMatchingProjects")},null,8,["modelValue","projects","empty-options-text"])],2)):F("",!0),l(w,{"model-value":p.value,label:"wipe",class:"mb-s","onUpdate:modelValue":s[2]||(s[2]=x=>p.value="wipe")},{default:i(()=>[l($,{color:"text-dark"},{default:i(()=>[b(u(r(j).baseText("projects.settings.delete.question.wipe.label")),1)]),_:1})]),_:1},8,["model-value"]),p.value==="wipe"?(h(),D("div",{key:1,class:S(d.$style.operation)},[l(z,{label:r(j).baseText("projects.settings.delete.question.wipe.title")},{default:i(()=>[l(O,{modelValue:y.value,"onUpdate:modelValue":s[3]||(s[3]=x=>y.value=x),placeholder:r(j).baseText("projects.settings.delete.question.wipe.placeholder")},null,8,["modelValue","placeholder"])]),_:1},8,["label"])],2)):F("",!0)])]),_:1},8,["modelValue","title"])}}}),we="_operation_1mn5e_1",ke={operation:we},Se={$style:ke},Me=ee(Ue,[["__cssModules",Se]]),$e={class:"pt-l"},Ce=G({__name:"ProjectRoleUpgradeDialog",props:W({limit:{},planName:{}},{modelValue:{type:Boolean},modelModifiers:{}}),emits:["update:modelValue"],setup(M){const f=M,n=Z(M,"modelValue"),o=fe(),N=J(),j=async()=>{await o.goToUpgrade("rbac","upgrade-rbac"),n.value=!1};return(g,p)=>{const y=v("i18n-t"),P=v("N8nButton"),U=v("el-dialog");return h(),H(U,{modelValue:n.value,"onUpdate:modelValue":p[1]||(p[1]=d=>n.value=d),title:r(N).baseText("projects.settings.role.upgrade.title"),width:"500"},{footer:i(()=>[l(P,{type:"secondary","native-type":"button",onClick:p[0]||(p[0]=d=>n.value=!1)},{default:i(()=>[b(u(r(N).baseText("generic.cancel")),1)]),_:1}),l(P,{type:"primary","native-type":"button",onClick:j},{default:i(()=>[b(u(r(N).baseText("projects.create.limitReached.link")),1)]),_:1})]),default:i(()=>[m("div",$e,[l(y,{keypath:"projects.settings.role.upgrade.message"},{planName:i(()=>[b(u(f.planName),1)]),limit:i(()=>[b(u(r(N).baseText("projects.create.limit",{adjustToNumber:f.limit,interpolate:{num:String(f.limit)}})),1)]),_:1})])]),_:1},8,["modelValue","title"])}}}),De={for:"name"},Ie={for:"projectMembers"},Be={key:0,class:"mr-2xs"},Re=m("hr",{class:"mb-2xl"},null,-1),Ae={class:"mb-xs"},Ee=m("br",null,null,-1),qe=G({__name:"ProjectSettings",setup(M){const f=ge(),n=J(),o=_e(),N=ye(),j=Pe(),g=xe(),p=ue(),y=Ve(),P=V(!1),U=V(!1),d=V(!1),s=V({name:"",relations:[]}),$=V({"project:editor":n.baseText("projects.settings.role.editor"),"project:admin":n.baseText("projects.settings.role.admin")}),w=V(null),O=B(()=>f.allUsers.filter(e=>!(s.value.relations||[]).find(a=>a.id===e.id))),z=B(()=>o.teamProjects.filter(e=>e.id!==o.currentProjectId)),I=B(()=>N.processedProjectRoles.map(e=>({...e,name:$.value[e.role]}))),R=B(()=>{var e;return(e=I.value.find(t=>t.licensed))==null?void 0:e.role}),A=e=>{d.value=!0;const t=f.getUserById(e);if(!t)return;const{id:a,firstName:c,lastName:C,email:k}=t,E={id:a,firstName:c,lastName:C,email:k};R.value&&(E.role=R.value),s.value.relations.push(E)},x=(e,t)=>{d.value=!0;const a=s.value.relations.findIndex(c=>c.id===e.id);t==="remove"?s.value.relations.splice(a,1):s.value.relations[a].role=t},te=()=>{d.value=!0},oe=()=>{var e,t;s.value.relations=(e=o.currentProject)!=null&&e.relations?Y(o.currentProject.relations):[],s.value.name=((t=o.currentProject)==null?void 0:t.name)??"",d.value=!1},se=()=>{const e={};return o.currentProject&&(s.value.name!==o.currentProject.name&&(e.name=s.value.name??""),s.value.relations.length!==o.currentProject.relations.length&&(e.memberAdded=s.value.relations.filter(t=>{var a;return!((a=o.currentProject)!=null&&a.relations.find(c=>c.id===t.id))}),e.memberRemoved=o.currentProject.relations.filter(t=>!s.value.relations.find(a=>a.id===t.id))),e.role=s.value.relations.filter(t=>{var c,C;const a=(c=o.currentProject)==null?void 0:c.relations.find(k=>k.id===t.id);return(a==null?void 0:a.role)!==t.role&&!((C=e.memberAdded)!=null&&C.find(k=>k.id===t.id))})),e},ae=e=>{var t;e.name&&y.track("User changed project name",{project_id:(t=o.currentProject)==null?void 0:t.id,name:e.name}),e.memberAdded&&e.memberAdded.forEach(a=>{var c;y.track("User added member to project",{project_id:(c=o.currentProject)==null?void 0:c.id,target_user_id:a.id,role:a.role})}),e.memberRemoved&&e.memberRemoved.forEach(a=>{var c;y.track("User removed member from project",{project_id:(c=o.currentProject)==null?void 0:c.id,target_user_id:a.id})}),e.role&&e.role.forEach(a=>{var c;y.track("User changed member role on project",{project_id:(c=o.currentProject)==null?void 0:c.id,target_user_id:a.id,role:a.role})})},re=async()=>{try{if(d.value&&o.currentProject){const e=se();await o.updateProject({id:o.currentProject.id,name:s.value.name,relations:s.value.relations.map(t=>({userId:t.id,role:t.role}))}),ae(e),d.value=!1,g.showMessage({title:n.baseText("projects.settings.save.successful.title",{interpolate:{projectName:s.value.name??""}}),type:"success"})}}catch(e){g.showError(e,n.baseText("projects.settings.save.error.title"))}},le=async()=>{await o.getAllProjects(),P.value=!0},ne=async e=>{var t;try{if(o.currentProject){const a=((t=o.currentProject)==null?void 0:t.name)??"";await o.deleteProject(o.currentProject.id,e),await p.push({name:Te.HOMEPAGE}),g.showMessage({title:n.baseText("projects.settings.delete.successful.title",{interpolate:{projectName:a}}),type:"success"}),P.value=!0}}catch(a){g.showError(a,n.baseText("projects.settings.delete.error.title"))}},ie=()=>{w.value&&s.value.name===n.baseText("projects.settings.newProjectName")&&(w.value.focus(),w.value.select())};return de(()=>o.currentProject,async()=>{var e,t;s.value.name=((e=o.currentProject)==null?void 0:e.name)??"",s.value.relations=(t=o.currentProject)!=null&&t.relations?Y(o.currentProject.relations):[],await je(),ie()},{immediate:!0}),pe(async()=>{await f.fetchUsers()}),(e,t)=>{var K,Q,X;const a=v("N8nInput"),c=v("N8nIcon"),C=v("N8nUserSelect"),k=v("N8nOption"),E=v("N8nSelect"),q=v("N8nButton"),ce=v("N8nUsersList");return h(),D("div",{class:S(e.$style.projectSettings)},[m("div",{class:S(e.$style.header)},[l(he)],2),m("form",{onSubmit:L(re,["prevent"])},[m("fieldset",null,[m("label",De,u(r(n).baseText("projects.settings.name")),1),l(a,{id:"name",ref_key:"nameInput",ref:w,modelValue:s.value.name,"onUpdate:modelValue":t[0]||(t[0]=_=>s.value.name=_),type:"text",name:"name",onInput:te},null,8,["modelValue"])]),m("fieldset",null,[m("label",Ie,u(r(n).baseText("projects.settings.projectMembers")),1),l(C,{id:"projectMembers",class:"mb-s",size:"large",users:O.value,"current-user-id":(K=r(f).currentUser)==null?void 0:K.id,placeholder:e.$locale.baseText("workflows.shareModal.select.placeholder"),"data-test-id":"project-members-select","onUpdate:modelValue":A},{prefix:i(()=>[l(c,{icon:"search"})]),_:1},8,["users","current-user-id","placeholder"]),l(ce,{actions:[],users:s.value.relations,"current-user-id":(Q=r(f).currentUser)==null?void 0:Q.id,"delete-label":e.$locale.baseText("workflows.shareModal.list.delete")},{actions:i(({user:_})=>[m("div",{class:S(e.$style.buttons)},[l(E,{class:"mr-2xs","model-value":(_==null?void 0:_.role)||I.value[0].role,size:"small","onUpdate:modelValue":T=>x(_,T)},{default:i(()=>[(h(!0),D(me,null,ve(I.value,T=>(h(),H(k,{key:T.role,value:T.role,label:T.name,disabled:!T.licensed},{default:i(()=>[b(u(T.name),1),T.licensed?F("",!0):(h(),D("span",{key:0,class:S(e.$style.upgrade),onClick:t[1]||(t[1]=He=>U.value=!0)},"  - "+u(r(n).baseText("generic.upgrade")),3))]),_:2},1032,["value","label","disabled"]))),128))]),_:2},1032,["model-value","onUpdate:modelValue"]),l(q,{type:"tertiary","native-type":"button",square:"",icon:"trash","data-test-id":"project-user-remove",onClick:T=>x(_,"remove")},null,8,["onClick"])],2)]),_:1},8,["users","current-user-id","delete-label"])]),m("fieldset",{class:S(e.$style.buttons)},[m("div",null,[d.value?(h(),D("small",Be,u(r(n).baseText("projects.settings.message.unsavedChanges")),1)):F("",!0),l(q,{disabled:!d.value,type:"secondary","native-type":"button",class:"mr-2xs","data-test-id":"project-settings-cancel-button",onClick:L(oe,["stop","prevent"])},{default:i(()=>[b(u(r(n).baseText("projects.settings.button.cancel")),1)]),_:1},8,["disabled"])]),l(q,{disabled:!d.value,type:"primary","data-test-id":"project-settings-save-button"},{default:i(()=>[b(u(r(n).baseText("projects.settings.button.save")),1)]),_:1},8,["disabled"])],2),m("fieldset",null,[Re,m("h3",Ae,u(r(n).baseText("projects.settings.danger.title")),1),m("small",null,u(r(n).baseText("projects.settings.danger.message")),1),Ee,l(q,{type:"tertiary","native-type":"button",class:"mt-s","data-test-id":"project-settings-delete-button",onClick:L(le,["stop","prevent"])},{default:i(()=>[b(u(r(n).baseText("projects.settings.danger.deleteProject")),1)]),_:1})])],32),l(Me,{modelValue:P.value,"onUpdate:modelValue":t[2]||(t[2]=_=>P.value=_),"current-project":r(o).currentProject,projects:z.value,onConfirmDelete:ne},null,8,["modelValue","current-project","projects"]),l(Ce,{modelValue:U.value,"onUpdate:modelValue":t[3]||(t[3]=_=>U.value=_),limit:r(o).teamProjectsLimit,"plan-name":(X=r(j).currentPlanData)==null?void 0:X.displayName},null,8,["modelValue","limit","plan-name"])],2)}}}),Le="_projectSettings_2vgb7_1",Fe="_header_2vgb7_21",Oe="_upgrade_2vgb7_27",ze="_buttons_2vgb7_31",We={projectSettings:Le,header:Fe,upgrade:Oe,buttons:ze},Ge={$style:We},Vt=ee(qe,[["__cssModules",Ge]]);export{Vt as default};
2
+ //# sourceMappingURL=ProjectSettings-kayD4yS7.js.map