n8n-editor-ui 1.93.0 → 1.95.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. package/dist/assets/{AnimatedSpinner-hbTZDd93.js → AnimatedSpinner-DlBYfeum.js} +1 -1
  2. package/dist/assets/{AnnotationTagsDropdown.ee.vue_vue_type_script_setup_true_lang-CYzc5StE.js → AnnotationTagsDropdown.ee.vue_vue_type_script_setup_true_lang-b_VpBPcV.js} +1 -1
  3. package/dist/assets/{AuthView-8SLMP0H_.js → AuthView-3BmNl_WD.js} +2 -2
  4. package/dist/assets/{CanvasChatSwitch-Dt8TgNJg.js → CanvasChatSwitch-C8GVNbZv.js} +16 -18
  5. package/dist/assets/{ChangePasswordView-DIRyDp89.js → ChangePasswordView-HptU1MSc.js} +3 -3
  6. package/dist/assets/CollectionParameter-DB_Or-wG.js +4 -0
  7. package/dist/assets/{CredentialsView-B6-VxAJ6.js → CredentialsView-Dx5hgaaC.js} +7 -7
  8. package/dist/assets/{DemoFooter-CIHwH5PG.js → DemoFooter-BkSVK4cp.js} +6 -8
  9. package/dist/assets/{ErrorView-C7i0TZwT.js → ErrorView-HDHwqLgc.js} +1 -1
  10. package/dist/assets/EvaluationsRootView-B5AhHo41.css +594 -0
  11. package/dist/assets/EvaluationsRootView-CwzFA39P.js +654 -0
  12. package/dist/assets/{TestDefinitionListView-Di-Edppe.css → EvaluationsView-6l_Invxt.css} +193 -76
  13. package/dist/assets/EvaluationsView-Y_Nzp-LP.js +570 -0
  14. package/dist/assets/{ExecutionsTime.vue_vue_type_script_setup_true_lang--2G21NNR.js → ExecutionsTime.vue_vue_type_script_setup_true_lang-BioZloew.js} +2 -2
  15. package/dist/assets/{ExecutionsView-C_YtciAr.js → ExecutionsView-SVk21vMq.js} +18 -18
  16. package/dist/assets/{FileSaver.min-bgn7Q9Gt.js → FileSaver.min-ZbRn_Jz1.js} +1 -1
  17. package/dist/assets/{FixedCollectionParameter-BPCJ5aaq.js → FixedCollectionParameter-iCfhPCTX.js} +1 -1
  18. package/dist/assets/{ForgotMyPasswordView-DyUaGd6Z.js → ForgotMyPasswordView-DID5un7M.js} +3 -3
  19. package/dist/assets/{InsightsChartAverageRuntime-BB2I2vpV.js → InsightsChartAverageRuntime-Db4OWo7M.js} +4 -4
  20. package/dist/assets/{InsightsChartFailed-CN_Rl3Bl.js → InsightsChartFailed-DjssZ9vc.js} +4 -4
  21. package/dist/assets/{InsightsChartFailureRate-CHKlg6tg.js → InsightsChartFailureRate-C4U_fOhA.js} +4 -4
  22. package/dist/assets/{InsightsChartTimeSaved-Cd05cM8q.js → InsightsChartTimeSaved-DmcamM8z.js} +4 -4
  23. package/dist/assets/{InsightsChartTotal-ChAO7myf.js → InsightsChartTotal-ywrK30zz.js} +4 -4
  24. package/dist/assets/{InsightsDashboard-Bx4vx9gz.css → InsightsDashboard-BSrakbzr.css} +42 -8
  25. package/dist/assets/{InsightsDashboard-BeCfBVUz.js → InsightsDashboard-CM-ieUCq.js} +43 -41
  26. package/dist/assets/{InsightsPaywall-Chz8CDc3.js → InsightsPaywall-D-bIgmwT.js} +1 -1
  27. package/dist/assets/InsightsSummary-CwTpu3sa.js +209 -0
  28. package/dist/assets/{InsightsSummary-CdlaUpAt.css → InsightsSummary-DzGQpM5h.css} +27 -24
  29. package/dist/assets/{InsightsTableWorkflows-5rpYY7YT.js → InsightsTableWorkflows-CVtm_fGN.js} +5 -6
  30. package/dist/assets/{InsightsTableWorkflows-Blv_GPUj.css → InsightsTableWorkflows-DfTZQkWL.css} +3 -4
  31. package/dist/assets/{Logo-DUDCllkm.js → Logo-nyJoHWQJ.js} +1 -1
  32. package/dist/assets/{LogsPanel-mTaFEGk_.css → LogsPanel-D7j-yJQx.css} +14 -14
  33. package/dist/assets/{LogsPanel-D9r5AcQH.js → LogsPanel-mX9Nf6VB.js} +457 -360
  34. package/dist/assets/{MainHeader-DkKOOZ_D.js → MainHeader-DrG-_mAG.js} +35 -25
  35. package/dist/assets/{MainHeader-CEMGASqv.css → MainHeader-Y95RcfHb.css} +18 -18
  36. package/dist/assets/{MainSidebar-ZUBIWeXm.js → MainSidebar-BMWCsLJG.js} +2 -2
  37. package/dist/assets/{NodeCreation-DCfAFuL5.js → NodeCreation-CO1xHNgA.js} +3 -4
  38. package/dist/assets/{NodeCreator-a0YVv1IE.js → NodeCreator-Bcr66G_2.js} +174 -69
  39. package/dist/assets/{NodeCreator-D18StsVZ.css → NodeCreator-Cp8Apzva.css} +38 -21
  40. package/dist/assets/{NodeDetailsView-C5_hVJzj.js → NodeDetailsView-BFW65Lly.js} +42 -19
  41. package/dist/assets/{NodeDetailsView-pYP-34nS.css → NodeDetailsView-BtWGMS7Y.css} +16 -16
  42. package/dist/assets/{useCanvasMapping-CTTq6x8X.js → NodeView-4aDk41Oy.js} +3559 -11337
  43. package/dist/assets/{useCanvasMapping-VtpW_QZA.css → NodeView-U4YkXSfU.css} +309 -6
  44. package/dist/assets/{ProjectCardBadge-DRlDZx3d.js → ProjectCardBadge-CLVVfcVb.js} +1 -1
  45. package/dist/assets/{ProjectHeader-DNm605Kk.js → ProjectHeader-DQk1kmw3.js} +2 -2
  46. package/dist/assets/{ProjectSettings-Dge_6KaR.js → ProjectSettings-BLTHRnTQ.js} +15 -4
  47. package/dist/assets/{PushConnectionTracker.vue_vue_type_script_setup_true_lang-CUf0LkWR.js → PushConnectionTracker.vue_vue_type_script_setup_true_lang-DhLSSpy6.js} +1 -1
  48. package/dist/assets/{ResourcesListLayout-Bbl-1i4l.js → ResourcesListLayout-BlDcQdXw.js} +2 -2
  49. package/dist/assets/{RunData-b0RE2JWc.js → RunData-C67Kx3bc.js} +234 -92
  50. package/dist/assets/{RunData-DQeENuzG.css → RunData-CE5FsU6k.css} +2 -2
  51. package/dist/assets/{RunDataAi-DnWcCR_0.js → RunDataAi-_rd0qTgN.js} +3 -4
  52. package/dist/assets/{RunDataJson-CptVuHuA.js → RunDataJson-BP0x4Zdv.js} +6 -7
  53. package/dist/assets/{RunDataJsonActions-3jjDztw7.js → RunDataJsonActions-Bc0fqS6Y.js} +1 -1
  54. package/dist/assets/{RunDataParsedAiContent-BbXv-NPD.js → RunDataParsedAiContent-l1979DuT.js} +4 -5
  55. package/dist/assets/{RunDataSearch-B90wjsDA.js → RunDataSearch-CCGPQjFW.js} +1 -1
  56. package/dist/assets/{RunDataTable-CpS78GlT.js → RunDataTable-uzdBjxmW.js} +2 -3
  57. package/dist/assets/{SamlOnboarding-Ch9K5rRW.js → SamlOnboarding-D4xkCaRS.js} +3 -3
  58. package/dist/assets/{SettingsApiView-9GU5n_rm.js → SettingsApiView-ijuSJs-i.js} +1 -1
  59. package/dist/assets/{SettingsCommunityNodesView-CPnVRzNX.js → SettingsCommunityNodesView-D3I8P7Ea.js} +4 -4
  60. package/dist/assets/{SettingsExternalSecrets-D7xTMV9h.js → SettingsExternalSecrets-ndwnYVtu.js} +1 -1
  61. package/dist/assets/{SettingsLdapView-OfrjGKkt.js → SettingsLdapView-Dzhh3gD4.js} +1 -1
  62. package/dist/assets/{SettingsLogStreamingView-C_VnOaeX.js → SettingsLogStreamingView-D-Rr-Jph.js} +1 -1
  63. package/dist/assets/{SettingsPersonalView-Dm24akPV.js → SettingsPersonalView-Cf1cBUw8.js} +1 -1
  64. package/dist/assets/{SettingsSourceControl-DDCmL82j.js → SettingsSourceControl-BXRyD_N0.js} +1 -1
  65. package/dist/assets/{SettingsSso-BGGQ0Cpg.js → SettingsSso-DZTsjRCO.js} +1 -1
  66. package/dist/assets/{SettingsUsageAndPlan-BzO_zdkH.js → SettingsUsageAndPlan-BqY4ptNL.js} +1 -1
  67. package/dist/assets/{SettingsUsersView-DHQUqhqB.js → SettingsUsersView-eqXFp615.js} +1 -1
  68. package/dist/assets/{SettingsView-CbtAqjOX.js → SettingsView-CHSTMDKz.js} +1 -1
  69. package/dist/assets/{SetupView-BME1OE6U.js → SetupView-D6-b4i8i.js} +3 -3
  70. package/dist/assets/{SetupWorkflowCredentialsButton-DZr4TCPC.js → SetupWorkflowCredentialsButton-6SWeqGx-.js} +1 -1
  71. package/dist/assets/{SetupWorkflowFromTemplateView-CPkKEY04.js → SetupWorkflowFromTemplateView-DTZ8dEhY.js} +3 -3
  72. package/dist/assets/{SigninView-DUeRvOiY.js → SigninView-B3mpecGJ.js} +3 -3
  73. package/dist/assets/{SignoutView-BC7SBunZ.js → SignoutView-Bq9cEhcZ.js} +1 -1
  74. package/dist/assets/{SignupView-B5ecYJ2q.js → SignupView-BTyAq-gW.js} +3 -3
  75. package/dist/assets/{TemplateDetails-DjanZgC1.js → TemplateDetails-Bf7Xg-KJ.js} +1 -1
  76. package/dist/assets/{TemplateList-8TyNGxY-.js → TemplateList-BmXxTP4v.js} +1 -1
  77. package/dist/assets/{TemplatesCollectionView-BkH4pJCv.js → TemplatesCollectionView-DKwycT_4.js} +5 -5
  78. package/dist/assets/{TemplatesSearchView-Bcdhi1SL.js → TemplatesSearchView-ciluP1sL.js} +3 -3
  79. package/dist/assets/{TemplatesView-De2XB6We.js → TemplatesView-CDdQbnxe.js} +1 -1
  80. package/dist/assets/{TemplatesWorkflowView-BVnwtrMa.js → TemplatesWorkflowView-uQ3eG-nR.js} +5 -5
  81. package/dist/assets/{VariablesView-BZCvPfan.js → VariablesView-Bve2WEng.js} +4 -4
  82. package/dist/assets/{WorkerView-CigxqnWi.js → WorkerView-CUyaAqvY.js} +6 -6
  83. package/dist/assets/{WorkflowActivator-B7jRy4L1.js → WorkflowActivator-DZSvs7Ye.js} +11 -9
  84. package/dist/assets/{WorkflowExecutionsInfoAccordion-C_ZycbsF.js → WorkflowExecutionsInfoAccordion-DTbkpnyq.js} +1 -1
  85. package/dist/assets/{WorkflowExecutionsLandingPage-DOqrfKlC.js → WorkflowExecutionsLandingPage-DNc0pN7t.js} +2 -2
  86. package/dist/assets/{WorkflowExecutionsPreview-B4Cj2gXW.js → WorkflowExecutionsPreview-SdFojcu-.js} +5 -6
  87. package/dist/assets/{WorkflowExecutionsView-RXfP7zkJ.js → WorkflowExecutionsView-CAbXPlyv.js} +10 -11
  88. package/dist/assets/{WorkflowHistory-DrXrRwIS.js → WorkflowHistory-BIFuha5h.js} +3 -3
  89. package/dist/assets/{WorkflowOnboardingView-CXH1vCW2.js → WorkflowOnboardingView-DLRgnF3H.js} +1 -1
  90. package/dist/assets/{WorkflowPreview-B_MuFEV8.js → WorkflowPreview-DRSvh1f-.js} +1 -1
  91. package/dist/assets/{WorkflowsView-D90hfJ35.js → WorkflowsView-DOQhvV_X.js} +9 -9
  92. package/dist/assets/{useClearExecutionButtonVisible-Dwc1_eG9.js → canvas-CdHFQJm7.js} +3 -2
  93. package/dist/assets/{chartjs.utils-DalQn9bk.js → chartjs.utils-hlpJdzhb.js} +2 -2
  94. package/dist/assets/{easyAiWorkflowUtils-kgtpBx2h.js → easyAiWorkflowUtils-GnIqpmRr.js} +1 -1
  95. package/dist/assets/{global-link-actions-CnWOMvqA.js → global-link-actions-CExoAUZJ.js} +1 -1
  96. package/dist/assets/{import-curl-BvX_O56D.js → import-curl-D2S8-TVc.js} +1 -1
  97. package/dist/assets/{index-DZ6VpjNj.js → index-BSlk84mz.js} +79639 -67526
  98. package/dist/assets/{index-yNaoC3fo.css → index-DH8MNLw5.css} +195 -488
  99. package/dist/assets/{index-Bb2NNknG.js → index-lOeP0Jxq.js} +1 -1
  100. package/dist/assets/{pickBy-B_HGYyxS.js → pickBy-BoYQMT9v.js} +1 -1
  101. package/dist/assets/{polyfills-CLZ4X0Ad.js → polyfills-J2x06Gdp.js} +157 -224
  102. package/dist/assets/{templateActions-DQfZ3ni5.js → templateActions-CAEk7dfj.js} +1 -1
  103. package/dist/assets/{typescript.worker-BsxN2afA.js → typescript.worker-DIrCbxuR.js} +2 -2
  104. package/dist/assets/{useBeforeUnload-Cu0LPVWe.js → useBeforeUnload-COWlK6zC.js} +1 -1
  105. package/dist/assets/{useExecutionDebugging-rc72wLIp.js → useExecutionDebugging-DOtIA9Qr.js} +1 -1
  106. package/dist/assets/{useExecutionHelpers-DqwMonFW.js → useExecutionHelpers-q1_8c2Pm.js} +2 -3
  107. package/dist/assets/{useImportCurlCommand-D_onuFvo.js → useImportCurlCommand-CbwqixK0.js} +2 -2
  108. package/dist/assets/{useProjectPages-e8b03-5_.js → useProjectPages-DlqnxMvy.js} +1 -1
  109. package/dist/assets/{usePushConnection-wm-7Id6Q.js → usePushConnection-Bysa9RG-.js} +35 -111
  110. package/dist/assets/{useWorkflowActivate-65xML23U.js → useWorkflowActivate-B1ps647W.js} +1 -1
  111. package/dist/assets/{useWorkflowSaving-CUel20JA.js → useWorkflowSaving-BVNVyvlZ.js} +1 -1
  112. package/dist/index.html +3 -3
  113. package/package.json +1 -1
  114. package/tsconfig.json +1 -0
  115. package/vite.config.mts +4 -0
  116. package/dist/assets/CollectionParameter-Cj4t6-hd.js +0 -4
  117. package/dist/assets/InsightsSummary-MECenLJQ.js +0 -207
  118. package/dist/assets/NodeView-Bk9h8GYy.js +0 -1719
  119. package/dist/assets/NodeView-C3A-bM1O.css +0 -304
  120. package/dist/assets/TestDefinitionEditView-Cwkrz308.css +0 -1189
  121. package/dist/assets/TestDefinitionEditView-DjmPnrTk.js +0 -1464
  122. package/dist/assets/TestDefinitionListView-BL2s_qBZ.js +0 -631
  123. package/dist/assets/TestDefinitionNewView-B9BqJZST.js +0 -75
  124. package/dist/assets/TestDefinitionRootView-AlWyxbc0.js +0 -39
  125. package/dist/assets/TestDefinitionRootView-DFT60fWE.css +0 -126
  126. package/dist/assets/dateFormatter-BPfJSa6q.js +0 -21
  127. package/dist/assets/useCanvasOperations-u8oSDa_u.js +0 -2834
  128. package/dist/assets/useTestDefinitionForm-DlUOnNC0.js +0 -154
@@ -1,1719 +0,0 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/NodeCreation-DCfAFuL5.js","assets/index-DZ6VpjNj.js","assets/index-yNaoC3fo.css","assets/useCanvasOperations-u8oSDa_u.js","assets/NodeCreation-RKvezEeg.css","assets/NodeDetailsView-C5_hVJzj.js","assets/import-curl-BvX_O56D.js","assets/RunData-b0RE2JWc.js","assets/FileSaver.min-bgn7Q9Gt.js","assets/useExecutionHelpers-DqwMonFW.js","assets/dateFormatter-BPfJSa6q.js","assets/RunData-DQeENuzG.css","assets/RunDataAi-DnWcCR_0.js","assets/RunDataParsedAiContent-BbXv-NPD.js","assets/RunDataParsedAiContent-9EEUzCKp.css","assets/RunDataAi-D9VLFXIf.css","assets/useWorkflowActivate-65xML23U.js","assets/NodeDetailsView-pYP-34nS.css","assets/SetupWorkflowCredentialsButton-DZr4TCPC.js"])))=>i.map(i=>d[i]);
2
- import { d as defineComponent, h as resolveComponent, e as createBlock, g as openBlock, C as createEventBus, Y as useCssModule, bO as toRef, q as computed, r as ref, bP as refThrottled, i as createElementBlock, k as createBaseVNode, x as renderSlot, f as createCommentVNode, b7 as mergeProps, m as unref, n as normalizeClass, _ as _export_sfc, c as useI18n, bQ as KeyboardShortcutTooltip, w as withCtx, j as createVNode, b2 as withModifiers, bR as reactive, o as onMounted, bb as onUnmounted, l as createTextVNode, t as toDisplayString, b as useRouter, R as useRoute, a as useToast, a4 as useDocumentTitle, a5 as useWorkflowHelpers, bA as useNodeHelpers, bz as useNodeTypesStore, H as useUIStore, Q as useWorkflowsStore, a0 as useSourceControlStore, p as useSettingsStore, bS as useCredentialsStore, bT as useEnvironmentsStore, bU as useExternalSecretsStore, Z as useRootStore, at as useExecutionsStore, $ as useCanvasStore, a3 as useNpsSurveyStore, bV as useHistoryStore, a1 as useProjectsStore, u as useUsersStore, E as useTagsStore, P as usePushConnectionStore, as as useNDVStore, aN as useTemplatesStore, bW as useBuilderStore, a2 as useFoldersStore, bX as useAgentRequestStore, bB as useRunWorkflow, bf as useClipboard, S as PLACEHOLDER_EMPTY_WORKFLOW_ID, bY as NEW_WORKFLOW_ID, V as VIEWS, aZ as LOGS_PANEL_STATE, bZ as START_NODE_TYPE, b_ as getNodeViewTab, s as MAIN_HEADER_TABS, b$ as VALID_WORKFLOW_IMPORT_URL_REGEX, ai as useMessage, aj as MODAL_CONFIRM, c0 as jsonParse, a7 as getResourcePermissions, bk as CHAT_TRIGGER_NODE_TYPE, bl as MANUAL_CHAT_TRIGGER_NODE_TYPE, X as watch, c1 as onBeforeRouteLeave, az as onBeforeMount, ak as WORKFLOW_SETTINGS_MODAL_KEY, aP as useExternalHooks, c2 as onActivated, c3 as onDeactivated, y as onBeforeUnmount, c4 as Suspense, c5 as defineAsyncComponent, c6 as N8nCallout, ao as __vitePreload, aa as EnterpriseEditionFeature, z as nextTick, ag as useTelemetry, c7 as tryToParseNumber, ah as nodeViewEventBus, bm as NodeConnectionTypes, c8 as isValidNodeConnectionType, c9 as CanvasConnectionMode, ca as historyBus, aF as sourceControlEventBus, cb as getNodesWithNormalizedPosition, aq as h, cc as NODE_CREATOR_OPEN_SOURCES, cd as CanvasNodeRenderType, ay as STICKY_NODE_TYPE, ce as needsAgentInput, cf as FROM_AI_PARAMETERS_MODAL_KEY, cg as DRAG_EVENT_DATA_KEY } from "./index-DZ6VpjNj.js";
3
- import { u as useVueFlow, a as useCanvasMapping, C as Canvas } from "./useCanvasMapping-CTTq6x8X.js";
4
- import { g as globalLinkActionsEventBus } from "./global-link-actions-CnWOMvqA.js";
5
- import { u as useNodeCreatorStore, a as useCanvasOperations, c as createCanvasConnectionHandleString } from "./useCanvasOperations-u8oSDa_u.js";
6
- import { u as useExecutionDebugging } from "./useExecutionDebugging-rc72wLIp.js";
7
- import { u as useBeforeUnload } from "./useBeforeUnload-Cu0LPVWe.js";
8
- import { g as getEasyAiWorkflowJson } from "./easyAiWorkflowUtils-kgtpBx2h.js";
9
- import { u as useClearExecutionButtonVisible } from "./useClearExecutionButtonVisible-Dwc1_eG9.js";
10
- import { u as useWorkflowSaving } from "./useWorkflowSaving-CUel20JA.js";
11
- const _sfc_main$7 = /* @__PURE__ */ defineComponent({
12
- __name: "CanvasChatButton",
13
- props: {
14
- type: {},
15
- label: {}
16
- },
17
- setup(__props) {
18
- return (_ctx, _cache) => {
19
- const _component_N8nButton = resolveComponent("N8nButton");
20
- return openBlock(), createBlock(_component_N8nButton, {
21
- label: _ctx.label,
22
- size: "large",
23
- icon: "comment",
24
- type: _ctx.type,
25
- "data-test-id": "workflow-chat-button"
26
- }, null, 8, ["label", "type"]);
27
- };
28
- }
29
- });
30
- const _sfc_main$6 = /* @__PURE__ */ defineComponent({
31
- ...{
32
- inheritAttrs: false
33
- },
34
- __name: "WorkflowCanvas",
35
- props: {
36
- id: { default: "canvas" },
37
- workflow: {},
38
- workflowObject: {},
39
- fallbackNodes: { default: () => [] },
40
- showFallbackNodes: { type: Boolean, default: true },
41
- eventBus: { default: () => createEventBus() },
42
- readOnly: { type: Boolean },
43
- executing: { type: Boolean }
44
- },
45
- setup(__props) {
46
- const props = __props;
47
- const $style = useCssModule();
48
- const { onNodesInitialized } = useVueFlow({ id: props.id });
49
- const workflow = toRef(props, "workflow");
50
- const workflowObject = toRef(props, "workflowObject");
51
- const nodes = computed(() => {
52
- return props.showFallbackNodes ? [...props.workflow.nodes, ...props.fallbackNodes] : props.workflow.nodes;
53
- });
54
- const connections = computed(() => props.workflow.connections);
55
- const { nodes: mappedNodes, connections: mappedConnections } = useCanvasMapping({
56
- nodes,
57
- connections,
58
- workflowObject
59
- });
60
- const initialFitViewDone = ref(false);
61
- onNodesInitialized(() => {
62
- if (!initialFitViewDone.value || props.showFallbackNodes) {
63
- props.eventBus.emit("fitView");
64
- initialFitViewDone.value = true;
65
- }
66
- });
67
- const mappedNodesThrottled = refThrottled(mappedNodes, 200);
68
- const mappedConnectionsThrottled = refThrottled(mappedConnections, 200);
69
- return (_ctx, _cache) => {
70
- return openBlock(), createElementBlock("div", {
71
- class: normalizeClass(unref($style).wrapper),
72
- "data-test-id": "canvas-wrapper"
73
- }, [
74
- createBaseVNode("div", {
75
- class: normalizeClass(unref($style).canvas)
76
- }, [
77
- workflow.value ? (openBlock(), createBlock(Canvas, mergeProps({
78
- key: 0,
79
- id: _ctx.id,
80
- nodes: _ctx.executing ? unref(mappedNodesThrottled) : unref(mappedNodes),
81
- connections: _ctx.executing ? unref(mappedConnectionsThrottled) : unref(mappedConnections),
82
- "event-bus": _ctx.eventBus,
83
- "read-only": _ctx.readOnly
84
- }, _ctx.$attrs), null, 16, ["id", "nodes", "connections", "event-bus", "read-only"])) : createCommentVNode("", true)
85
- ], 2),
86
- renderSlot(_ctx.$slots, "default")
87
- ], 2);
88
- };
89
- }
90
- });
91
- const wrapper = "_wrapper_17o0o_123";
92
- const canvas = "_canvas_17o0o_131";
93
- const style0$1 = {
94
- wrapper,
95
- canvas
96
- };
97
- const cssModules$1 = {
98
- "$style": style0$1
99
- };
100
- const WorkflowCanvas = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["__cssModules", cssModules$1]]);
101
- const _sfc_main$5 = /* @__PURE__ */ defineComponent({
102
- __name: "CanvasRunWorkflowButton",
103
- props: {
104
- waitingForWebhook: { type: Boolean },
105
- executing: { type: Boolean },
106
- disabled: { type: Boolean }
107
- },
108
- emits: ["mouseenter", "mouseleave", "click"],
109
- setup(__props) {
110
- const props = __props;
111
- const i18n = useI18n();
112
- const label = computed(() => {
113
- if (!props.executing) {
114
- return i18n.baseText("nodeView.runButtonText.executeWorkflow");
115
- }
116
- if (props.waitingForWebhook) {
117
- return i18n.baseText("nodeView.runButtonText.waitingForTriggerEvent");
118
- }
119
- return i18n.baseText("nodeView.runButtonText.executingWorkflow");
120
- });
121
- return (_ctx, _cache) => {
122
- const _component_N8nButton = resolveComponent("N8nButton");
123
- return openBlock(), createBlock(KeyboardShortcutTooltip, {
124
- label: label.value,
125
- shortcut: { metaKey: true, keys: ["↵"] }
126
- }, {
127
- default: withCtx(() => [
128
- createVNode(_component_N8nButton, {
129
- loading: _ctx.executing,
130
- label: label.value,
131
- disabled: _ctx.disabled,
132
- size: "large",
133
- icon: "flask",
134
- type: "primary",
135
- "data-test-id": "execute-workflow-button",
136
- onMouseenter: _cache[0] || (_cache[0] = ($event) => _ctx.$emit("mouseenter", $event)),
137
- onMouseleave: _cache[1] || (_cache[1] = ($event) => _ctx.$emit("mouseleave", $event)),
138
- onClick: _cache[2] || (_cache[2] = withModifiers(($event) => _ctx.$emit("click", $event), ["stop"]))
139
- }, null, 8, ["loading", "label", "disabled"])
140
- ]),
141
- _: 1
142
- }, 8, ["label"]);
143
- };
144
- }
145
- });
146
- const state = reactive({
147
- customActions: {},
148
- delegatedClickHandler: null
149
- });
150
- function useGlobalLinkActions() {
151
- function registerCustomAction({ key, action }) {
152
- state.customActions[key] = action;
153
- }
154
- function unregisterCustomAction(key) {
155
- const { [key]: _, ...rest } = state.customActions;
156
- state.customActions = rest;
157
- }
158
- function getElementAttributes(element) {
159
- const attributesObject = {};
160
- for (let i = 0; i < element.attributes.length; i++) {
161
- const attr = element.attributes[i];
162
- if (attr.name.startsWith("data-action-parameter-")) {
163
- attributesObject[attr.name.replace("data-action-parameter-", "")] = attr.value;
164
- }
165
- }
166
- return attributesObject;
167
- }
168
- function delegateClick(e) {
169
- const clickedElement = e.target;
170
- if (!(clickedElement instanceof Element) || clickedElement.tagName !== "A") return;
171
- const actionAttribute = clickedElement.getAttribute("data-action");
172
- if (actionAttribute && typeof availableActions.value[actionAttribute] === "function") {
173
- e.preventDefault();
174
- const elementAttributes = getElementAttributes(clickedElement);
175
- availableActions.value[actionAttribute](elementAttributes);
176
- }
177
- }
178
- function reload() {
179
- if (window.top) {
180
- window.top.location.reload();
181
- } else {
182
- window.location.reload();
183
- }
184
- }
185
- const availableActions = computed(() => ({
186
- reload,
187
- ...state.customActions
188
- }));
189
- onMounted(() => {
190
- if (state.delegatedClickHandler) return;
191
- state.delegatedClickHandler = delegateClick;
192
- window.addEventListener("click", delegateClick);
193
- globalLinkActionsEventBus.on("registerGlobalLinkAction", registerCustomAction);
194
- });
195
- onUnmounted(() => {
196
- window.removeEventListener("click", delegateClick);
197
- state.delegatedClickHandler = null;
198
- globalLinkActionsEventBus.off("registerGlobalLinkAction", registerCustomAction);
199
- });
200
- return {
201
- registerCustomAction,
202
- unregisterCustomAction
203
- };
204
- }
205
- const _sfc_main$4 = /* @__PURE__ */ defineComponent({
206
- __name: "CanvasStopCurrentExecutionButton",
207
- props: {
208
- stopping: { type: Boolean }
209
- },
210
- setup(__props) {
211
- const props = __props;
212
- const i18n = useI18n();
213
- const title = computed(
214
- () => props.stopping ? i18n.baseText("nodeView.stoppingCurrentExecution") : i18n.baseText("nodeView.stopCurrentExecution")
215
- );
216
- return (_ctx, _cache) => {
217
- const _component_N8nIconButton = resolveComponent("N8nIconButton");
218
- return openBlock(), createBlock(_component_N8nIconButton, {
219
- icon: "stop",
220
- size: "large",
221
- class: "stop-execution",
222
- type: "secondary",
223
- title: title.value,
224
- loading: _ctx.stopping,
225
- "data-test-id": "stop-execution-button"
226
- }, null, 8, ["title", "loading"]);
227
- };
228
- }
229
- });
230
- const _sfc_main$3 = /* @__PURE__ */ defineComponent({
231
- __name: "CanvasStopWaitingForWebhookButton",
232
- setup(__props) {
233
- const i18n = useI18n();
234
- return (_ctx, _cache) => {
235
- const _component_N8nIconButton = resolveComponent("N8nIconButton");
236
- return openBlock(), createBlock(_component_N8nIconButton, {
237
- class: "stop-execution",
238
- icon: "stop",
239
- size: "large",
240
- title: unref(i18n).baseText("nodeView.stopWaitingForWebhookCall"),
241
- type: "secondary",
242
- "data-test-id": "stop-execution-waiting-for-webhook-button"
243
- }, null, 8, ["title"]);
244
- };
245
- }
246
- });
247
- const _sfc_main$2 = /* @__PURE__ */ defineComponent({
248
- __name: "CanvasClearExecutionDataButton",
249
- setup(__props) {
250
- const i18n = useI18n();
251
- return (_ctx, _cache) => {
252
- const _component_N8nIconButton = resolveComponent("N8nIconButton");
253
- return openBlock(), createBlock(_component_N8nIconButton, {
254
- title: unref(i18n).baseText("nodeView.deletesTheCurrentExecutionData"),
255
- icon: "trash",
256
- size: "large",
257
- "data-test-id": "clear-execution-data-button"
258
- }, null, 8, ["title"]);
259
- };
260
- }
261
- });
262
- const _hoisted_1 = { "data-action": "reload" };
263
- const _hoisted_2 = {
264
- href: "https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.wait/",
265
- target: "_blank"
266
- };
267
- const _sfc_main$1 = /* @__PURE__ */ defineComponent({
268
- __name: "NodeViewUnfinishedWorkflowMessage",
269
- setup(__props) {
270
- const i18 = useI18n();
271
- return (_ctx, _cache) => {
272
- return openBlock(), createElementBlock("div", null, [
273
- createBaseVNode("a", _hoisted_1, toDisplayString(unref(i18).baseText("nodeView.refresh")), 1),
274
- createTextVNode(" " + toDisplayString(unref(i18).baseText("nodeView.toSeeTheLatestStatus")) + ". ", 1),
275
- _cache[0] || (_cache[0] = createBaseVNode("br", null, null, -1)),
276
- createBaseVNode("a", _hoisted_2, toDisplayString(unref(i18).baseText("nodeView.moreInfo")), 1)
277
- ]);
278
- };
279
- }
280
- });
281
- const _sfc_main = /* @__PURE__ */ defineComponent({
282
- ...{
283
- name: "NodeView"
284
- },
285
- __name: "NodeView",
286
- setup(__props) {
287
- const LazyNodeCreation = defineAsyncComponent(
288
- async () => await __vitePreload(() => import("./NodeCreation-DCfAFuL5.js").then((n) => n.N), true ? __vite__mapDeps([0,1,2,3,4]) : void 0)
289
- );
290
- const LazyNodeDetailsView = defineAsyncComponent(
291
- async () => await __vitePreload(() => import("./NodeDetailsView-C5_hVJzj.js"), true ? __vite__mapDeps([5,1,2,6,7,8,9,10,11,12,13,14,3,15,16,17]) : void 0)
292
- );
293
- const LazySetupWorkflowCredentialsButton = defineAsyncComponent(
294
- async () => await __vitePreload(() => import("./SetupWorkflowCredentialsButton-DZr4TCPC.js"), true ? __vite__mapDeps([18,1,2]) : void 0)
295
- );
296
- const $style = useCssModule();
297
- const router = useRouter();
298
- const route = useRoute();
299
- const i18n = useI18n();
300
- const telemetry = useTelemetry();
301
- const externalHooks = useExternalHooks();
302
- const toast = useToast();
303
- const message = useMessage();
304
- const documentTitle = useDocumentTitle();
305
- const workflowHelpers = useWorkflowHelpers({ router });
306
- const nodeHelpers = useNodeHelpers();
307
- const nodeTypesStore = useNodeTypesStore();
308
- const uiStore = useUIStore();
309
- const workflowsStore = useWorkflowsStore();
310
- const sourceControlStore = useSourceControlStore();
311
- const nodeCreatorStore = useNodeCreatorStore();
312
- const settingsStore = useSettingsStore();
313
- const credentialsStore = useCredentialsStore();
314
- const environmentsStore = useEnvironmentsStore();
315
- const externalSecretsStore = useExternalSecretsStore();
316
- const rootStore = useRootStore();
317
- const executionsStore = useExecutionsStore();
318
- const canvasStore = useCanvasStore();
319
- const npsSurveyStore = useNpsSurveyStore();
320
- const historyStore = useHistoryStore();
321
- const projectsStore = useProjectsStore();
322
- const usersStore = useUsersStore();
323
- const tagsStore = useTagsStore();
324
- const pushConnectionStore = usePushConnectionStore();
325
- const ndvStore = useNDVStore();
326
- const templatesStore = useTemplatesStore();
327
- const builderStore = useBuilderStore();
328
- const foldersStore = useFoldersStore();
329
- const agentRequestStore = useAgentRequestStore();
330
- const canvasEventBus = createEventBus();
331
- const { addBeforeUnloadEventBindings, removeBeforeUnloadEventBindings } = useBeforeUnload({
332
- route
333
- });
334
- const { registerCustomAction, unregisterCustomAction } = useGlobalLinkActions();
335
- const { runWorkflow, runEntireWorkflow, stopCurrentExecution, stopWaitingForWebhook } = useRunWorkflow({ router });
336
- const {
337
- updateNodePosition,
338
- updateNodesPosition,
339
- tidyUp,
340
- revertUpdateNodePosition,
341
- renameNode,
342
- revertRenameNode,
343
- setNodeActive,
344
- setNodeSelected,
345
- toggleNodesDisabled,
346
- revertToggleNodeDisabled,
347
- toggleNodesPinned,
348
- setNodeParameters,
349
- deleteNode,
350
- deleteNodes,
351
- copyNodes,
352
- cutNodes,
353
- duplicateNodes,
354
- revertDeleteNode,
355
- addNodes,
356
- importTemplate,
357
- revertAddNode,
358
- createConnection,
359
- revertCreateConnection,
360
- deleteConnection,
361
- revertDeleteConnection,
362
- revalidateNodeInputConnections,
363
- revalidateNodeOutputConnections,
364
- setNodeActiveByName,
365
- clearNodeActive,
366
- addConnections,
367
- tryToOpenSubworkflowInNewTab,
368
- importWorkflowData,
369
- fetchWorkflowDataFromUrl,
370
- resetWorkspace,
371
- initializeWorkspace,
372
- openExecution,
373
- editableWorkflow,
374
- editableWorkflowObject,
375
- lastClickPosition,
376
- toggleChatOpen
377
- } = useCanvasOperations({ router });
378
- const { applyExecutionData } = useExecutionDebugging();
379
- useClipboard({ onPaste: onClipboardPaste });
380
- const isLoading = ref(true);
381
- const isBlankRedirect = ref(false);
382
- const readOnlyNotification = ref(null);
383
- const isProductionExecutionPreview = ref(false);
384
- const isExecutionPreview = ref(false);
385
- const canOpenNDV = ref(true);
386
- const hideNodeIssues = ref(false);
387
- const fallbackNodes = ref([]);
388
- const initializedWorkflowId = ref();
389
- const workflowId = computed(() => {
390
- const workflowIdParam = route.params.name;
391
- return [PLACEHOLDER_EMPTY_WORKFLOW_ID, NEW_WORKFLOW_ID].includes(workflowIdParam) ? void 0 : workflowIdParam;
392
- });
393
- const routeNodeId = computed(() => route.params.nodeId);
394
- const isNewWorkflowRoute = computed(() => route.name === VIEWS.NEW_WORKFLOW || !workflowId.value);
395
- const isWorkflowRoute = computed(() => !!route?.meta?.nodeView || isDemoRoute.value);
396
- const isDemoRoute = computed(() => route.name === VIEWS.DEMO);
397
- const isReadOnlyRoute = computed(() => !!route?.meta?.readOnlyCanvas);
398
- const isReadOnlyEnvironment = computed(() => {
399
- return sourceControlStore.preferences.branchReadOnly;
400
- });
401
- const isCanvasReadOnly = computed(() => {
402
- return isDemoRoute.value || isReadOnlyEnvironment.value || !(workflowPermissions.value.update ?? projectPermissions.value.workflow.update) || editableWorkflow.value.isArchived;
403
- });
404
- const showFallbackNodes = computed(() => triggerNodes.value.length === 0);
405
- const keyBindingsEnabled = computed(() => {
406
- return !ndvStore.activeNode && uiStore.activeModals.length === 0;
407
- });
408
- const isLogsPanelOpen = computed(() => workflowsStore.logsPanelState !== LOGS_PANEL_STATE.CLOSED);
409
- async function initializeData() {
410
- const loadPromises = (() => {
411
- if (settingsStore.isPreviewMode && isDemoRoute.value) return [];
412
- const promises = [
413
- workflowsStore.fetchActiveWorkflows(),
414
- credentialsStore.fetchAllCredentials(),
415
- credentialsStore.fetchCredentialTypes(true)
416
- ];
417
- if (settingsStore.isEnterpriseFeatureEnabled[EnterpriseEditionFeature.Variables]) {
418
- promises.push(environmentsStore.fetchAllVariables());
419
- }
420
- if (settingsStore.isEnterpriseFeatureEnabled[EnterpriseEditionFeature.ExternalSecrets]) {
421
- promises.push(externalSecretsStore.fetchAllSecrets());
422
- }
423
- return promises;
424
- })();
425
- if (nodeTypesStore.allNodeTypes.length === 0) {
426
- loadPromises.push(nodeTypesStore.getNodeTypes());
427
- }
428
- try {
429
- await Promise.all(loadPromises);
430
- } catch (error) {
431
- toast.showError(
432
- error,
433
- i18n.baseText("nodeView.showError.mounted1.title"),
434
- i18n.baseText("nodeView.showError.mounted1.message") + ":"
435
- );
436
- return;
437
- }
438
- }
439
- async function initializeRoute(force = false) {
440
- if (route.query.action === "workflowSave") {
441
- uiStore.stateIsDirty = false;
442
- await router.replace({
443
- query: { ...route.query, action: void 0 }
444
- });
445
- return;
446
- }
447
- const isAlreadyInitialized = !force && initializedWorkflowId.value && [NEW_WORKFLOW_ID, workflowId.value].includes(initializedWorkflowId.value);
448
- if (isBlankRedirect.value) {
449
- isBlankRedirect.value = false;
450
- } else if (route.name === VIEWS.TEMPLATE_IMPORT) {
451
- const templateId = route.params.id;
452
- const loadWorkflowFromJSON = route.query.fromJson === "true";
453
- if (loadWorkflowFromJSON) {
454
- const easyAiWorkflowJson = getEasyAiWorkflowJson();
455
- await openTemplateFromWorkflowJSON(easyAiWorkflowJson);
456
- } else {
457
- await openWorkflowTemplate(templateId.toString());
458
- }
459
- } else if (isWorkflowRoute.value) {
460
- if (!isAlreadyInitialized) {
461
- historyStore.reset();
462
- if (!isDemoRoute.value) {
463
- await loadCredentials();
464
- }
465
- if (isNewWorkflowRoute.value || !workflowId.value) {
466
- if (route.meta?.nodeView === true) {
467
- await initializeWorkspaceForNewWorkflow();
468
- }
469
- return;
470
- }
471
- await initializeWorkspaceForExistingWorkflow(workflowId.value);
472
- void nextTick(() => {
473
- updateNodesIssues();
474
- });
475
- }
476
- if (route.name === VIEWS.EXECUTION_DEBUG) {
477
- await initializeDebugMode();
478
- }
479
- }
480
- }
481
- async function initializeWorkspaceForNewWorkflow() {
482
- resetWorkspace();
483
- const parentFolderId = route.query.parentFolderId;
484
- await workflowsStore.getNewWorkflowDataAndMakeShareable(
485
- void 0,
486
- projectsStore.currentProjectId,
487
- parentFolderId
488
- );
489
- if (projectsStore.currentProjectId) {
490
- await fetchAndSetProject(projectsStore.currentProjectId);
491
- }
492
- await fetchAndSetParentFolder(parentFolderId);
493
- uiStore.nodeViewInitialized = true;
494
- initializedWorkflowId.value = NEW_WORKFLOW_ID;
495
- }
496
- async function fetchAndSetParentFolder(folderId) {
497
- if (folderId) {
498
- let parentFolder = foldersStore.getCachedFolder(folderId);
499
- if (!parentFolder && projectsStore.currentProjectId) {
500
- await foldersStore.getFolderPath(projectsStore.currentProjectId, folderId);
501
- parentFolder = foldersStore.getCachedFolder(folderId);
502
- }
503
- if (parentFolder) {
504
- workflowsStore.setParentFolder({
505
- ...parentFolder,
506
- parentFolderId: parentFolder.parentFolder ?? null
507
- });
508
- }
509
- }
510
- }
511
- async function fetchAndSetProject(projectId) {
512
- if (!projectsStore.currentProject) {
513
- const project = await projectsStore.fetchProject(projectId);
514
- projectsStore.setCurrentProject(project);
515
- }
516
- }
517
- async function initializeWorkspaceForExistingWorkflow(id) {
518
- try {
519
- const workflowData = await workflowsStore.fetchWorkflow(id);
520
- openWorkflow(workflowData);
521
- if (workflowData.parentFolder) {
522
- workflowsStore.setParentFolder(workflowData.parentFolder);
523
- }
524
- if (workflowData.meta?.onboardingId) {
525
- trackOpenWorkflowFromOnboardingTemplate();
526
- }
527
- await projectsStore.setProjectNavActiveIdByWorkflowHomeProject(workflowData.homeProject);
528
- } catch (error) {
529
- toast.showError(error, i18n.baseText("openWorkflow.workflowNotFoundError"));
530
- void router.push({
531
- name: VIEWS.NEW_WORKFLOW
532
- });
533
- } finally {
534
- uiStore.nodeViewInitialized = true;
535
- initializedWorkflowId.value = workflowId.value;
536
- }
537
- }
538
- function updateNodesIssues() {
539
- nodeHelpers.updateNodesInputIssues();
540
- nodeHelpers.updateNodesCredentialsIssues();
541
- nodeHelpers.updateNodesParameterIssues();
542
- }
543
- function openWorkflow(data) {
544
- resetWorkspace();
545
- workflowHelpers.setDocumentTitle(data.name, "IDLE");
546
- initializeWorkspace(data);
547
- void externalHooks.run("workflow.open", {
548
- workflowId: data.id,
549
- workflowName: data.name
550
- });
551
- fitView();
552
- }
553
- function trackOpenWorkflowFromOnboardingTemplate() {
554
- telemetry.track(
555
- `User opened workflow from onboarding template with ID ${editableWorkflow.value.meta?.onboardingId}`,
556
- {
557
- workflow_id: workflowId.value
558
- },
559
- {
560
- withPostHog: true
561
- }
562
- );
563
- }
564
- async function openTemplateFromWorkflowJSON(workflow) {
565
- if (!workflow.nodes || !workflow.connections) {
566
- toast.showError(
567
- new Error(i18n.baseText("nodeView.couldntLoadWorkflow.invalidWorkflowObject")),
568
- i18n.baseText("nodeView.couldntImportWorkflow")
569
- );
570
- await router.replace({ name: VIEWS.NEW_WORKFLOW });
571
- return;
572
- }
573
- resetWorkspace();
574
- canvasStore.startLoading();
575
- canvasStore.setLoadingText(i18n.baseText("nodeView.loadingTemplate"));
576
- workflowsStore.currentWorkflowExecutions = [];
577
- executionsStore.activeExecution = null;
578
- isBlankRedirect.value = true;
579
- const templateId = workflow.meta.templateId;
580
- const parentFolderId = route.query.parentFolderId;
581
- await router.replace({
582
- name: VIEWS.NEW_WORKFLOW,
583
- query: { templateId, parentFolderId }
584
- });
585
- await importTemplate({ id: templateId, name: workflow.name, workflow });
586
- uiStore.stateIsDirty = true;
587
- canvasStore.stopLoading();
588
- fitView();
589
- }
590
- async function openWorkflowTemplate(templateId) {
591
- resetWorkspace();
592
- canvasStore.startLoading();
593
- canvasStore.setLoadingText(i18n.baseText("nodeView.loadingTemplate"));
594
- workflowsStore.currentWorkflowExecutions = [];
595
- executionsStore.activeExecution = null;
596
- let data;
597
- try {
598
- void externalHooks.run("template.requested", { templateId });
599
- data = await templatesStore.getFixedWorkflowTemplate(templateId);
600
- if (!data) {
601
- throw new Error(
602
- i18n.baseText("nodeView.workflowTemplateWithIdCouldNotBeFound", {
603
- interpolate: { templateId }
604
- })
605
- );
606
- }
607
- } catch (error) {
608
- toast.showError(error, i18n.baseText("nodeView.couldntImportWorkflow"));
609
- await router.replace({ name: VIEWS.NEW_WORKFLOW });
610
- return;
611
- }
612
- trackOpenWorkflowTemplate(templateId);
613
- isBlankRedirect.value = true;
614
- await router.replace({ name: VIEWS.NEW_WORKFLOW, query: { templateId } });
615
- await importTemplate({ id: templateId, name: data.name, workflow: data.workflow });
616
- uiStore.stateIsDirty = true;
617
- canvasStore.stopLoading();
618
- void externalHooks.run("template.open", {
619
- templateId,
620
- templateName: data.name,
621
- workflow: data.workflow
622
- });
623
- fitView();
624
- }
625
- function trackOpenWorkflowTemplate(templateId) {
626
- telemetry.track(
627
- "User inserted workflow template",
628
- {
629
- source: "workflow",
630
- template_id: tryToParseNumber(templateId),
631
- wf_template_repo_session_id: templatesStore.previousSessionId
632
- },
633
- {
634
- withPostHog: true
635
- }
636
- );
637
- }
638
- const triggerNodes = computed(() => {
639
- return editableWorkflow.value.nodes.filter(
640
- (node) => node.type === START_NODE_TYPE || nodeTypesStore.isTriggerNode(node.type)
641
- );
642
- });
643
- const containsTriggerNodes = computed(() => triggerNodes.value.length > 0);
644
- const allTriggerNodesDisabled = computed(() => {
645
- const disabledTriggerNodes = triggerNodes.value.filter((node) => node.disabled);
646
- return disabledTriggerNodes.length === triggerNodes.value.length;
647
- });
648
- function onTidyUp(event) {
649
- tidyUp(event);
650
- }
651
- function onUpdateNodesPosition(events) {
652
- updateNodesPosition(events, { trackHistory: true });
653
- }
654
- function onUpdateNodePosition(id, position) {
655
- updateNodePosition(id, position, { trackHistory: true });
656
- }
657
- function onRevertNodePosition({ nodeName, position }) {
658
- revertUpdateNodePosition(nodeName, { x: position[0], y: position[1] });
659
- }
660
- function onDeleteNode(id) {
661
- const matchedFallbackNode = fallbackNodes.value.findIndex((node) => node.id === id);
662
- if (matchedFallbackNode >= 0) {
663
- fallbackNodes.value.splice(matchedFallbackNode, 1);
664
- } else {
665
- deleteNode(id, { trackHistory: true });
666
- }
667
- }
668
- function onDeleteNodes(ids) {
669
- deleteNodes(ids);
670
- }
671
- function onRevertDeleteNode({ node }) {
672
- revertDeleteNode(node);
673
- }
674
- function onToggleNodeDisabled(id) {
675
- if (!checkIfEditingIsAllowed()) {
676
- return;
677
- }
678
- toggleNodesDisabled([id]);
679
- }
680
- function onRevertToggleNodeDisabled({ nodeName }) {
681
- revertToggleNodeDisabled(nodeName);
682
- }
683
- function onToggleNodesDisabled(ids) {
684
- if (!checkIfEditingIsAllowed()) {
685
- return;
686
- }
687
- toggleNodesDisabled(ids);
688
- }
689
- function onClickNode() {
690
- closeNodeCreator();
691
- }
692
- function onSetNodeActivated(id, event) {
693
- if (event?.metaKey || event?.ctrlKey) {
694
- const didOpen = tryToOpenSubworkflowInNewTab(id);
695
- if (didOpen) {
696
- return;
697
- }
698
- }
699
- setNodeActive(id);
700
- }
701
- function onOpenSubWorkflow(id) {
702
- tryToOpenSubworkflowInNewTab(id);
703
- }
704
- function onSetNodeDeactivated() {
705
- clearNodeActive();
706
- }
707
- function onSetNodeSelected(id) {
708
- closeNodeCreator();
709
- setNodeSelected(id);
710
- }
711
- async function onCopyNodes(ids) {
712
- await copyNodes(ids);
713
- toast.showMessage({ title: i18n.baseText("generic.copiedToClipboard"), type: "success" });
714
- }
715
- async function onClipboardPaste(plainTextData) {
716
- if (getNodeViewTab(route) !== MAIN_HEADER_TABS.WORKFLOW || !keyBindingsEnabled.value || !checkIfEditingIsAllowed()) {
717
- return;
718
- }
719
- let workflowData = null;
720
- if (plainTextData.match(VALID_WORKFLOW_IMPORT_URL_REGEX)) {
721
- const importConfirm = await message.confirm(
722
- i18n.baseText("nodeView.confirmMessage.onClipboardPasteEvent.message", {
723
- interpolate: { plainTextData }
724
- }),
725
- i18n.baseText("nodeView.confirmMessage.onClipboardPasteEvent.headline"),
726
- {
727
- type: "warning",
728
- confirmButtonText: i18n.baseText(
729
- "nodeView.confirmMessage.onClipboardPasteEvent.confirmButtonText"
730
- ),
731
- cancelButtonText: i18n.baseText(
732
- "nodeView.confirmMessage.onClipboardPasteEvent.cancelButtonText"
733
- )
734
- }
735
- );
736
- if (importConfirm !== MODAL_CONFIRM) {
737
- return;
738
- }
739
- workflowData = await fetchWorkflowDataFromUrl(plainTextData);
740
- } else {
741
- workflowData = jsonParse(plainTextData, { fallbackValue: null });
742
- }
743
- if (!workflowData) {
744
- return;
745
- }
746
- const result = await importWorkflowData(workflowData, "paste", false);
747
- selectNodes(result.nodes?.map((node) => node.id) ?? []);
748
- }
749
- async function onCutNodes(ids) {
750
- if (isCanvasReadOnly.value) {
751
- await copyNodes(ids);
752
- } else {
753
- await cutNodes(ids);
754
- }
755
- }
756
- async function onDuplicateNodes(ids) {
757
- if (!checkIfEditingIsAllowed()) {
758
- return;
759
- }
760
- const newIds = await duplicateNodes(ids);
761
- selectNodes(newIds);
762
- }
763
- function onPinNodes(ids, source) {
764
- if (!checkIfEditingIsAllowed()) {
765
- return;
766
- }
767
- toggleNodesPinned(ids, source);
768
- }
769
- async function onSaveWorkflow() {
770
- const workflowIsSaved = !uiStore.stateIsDirty;
771
- const workflowIsArchived = workflowsStore.workflow.isArchived;
772
- if (workflowIsSaved || workflowIsArchived) {
773
- return;
774
- }
775
- const saved = await workflowHelpers.saveCurrentWorkflow();
776
- if (saved) {
777
- canvasEventBus.emit("saved:workflow");
778
- }
779
- }
780
- function addWorkflowSavedEventBindings() {
781
- canvasEventBus.on("saved:workflow", npsSurveyStore.fetchPromptsData);
782
- canvasEventBus.on("saved:workflow", onSaveFromWithinNDV);
783
- }
784
- function removeWorkflowSavedEventBindings() {
785
- canvasEventBus.off("saved:workflow", npsSurveyStore.fetchPromptsData);
786
- canvasEventBus.off("saved:workflow", onSaveFromWithinNDV);
787
- canvasEventBus.off("saved:workflow", onSaveFromWithinExecutionDebug);
788
- }
789
- async function onSaveFromWithinNDV() {
790
- if (ndvStore.activeNodeName) {
791
- toast.showMessage({
792
- title: i18n.baseText("generic.workflowSaved"),
793
- type: "success"
794
- });
795
- }
796
- }
797
- async function onCreateWorkflow() {
798
- await router.push({ name: VIEWS.NEW_WORKFLOW });
799
- }
800
- function onRenameNode(parameterData) {
801
- if (parameterData.name === "name" && parameterData.oldValue) {
802
- void renameNode(parameterData.oldValue, parameterData.value);
803
- }
804
- }
805
- async function onOpenRenameNodeModal(id) {
806
- const currentName = workflowsStore.getNodeById(id)?.name ?? "";
807
- if (!keyBindingsEnabled.value || document.querySelector(".rename-prompt")) return;
808
- try {
809
- const promptResponsePromise = message.prompt(
810
- i18n.baseText("nodeView.prompt.newName") + ":",
811
- i18n.baseText("nodeView.prompt.renameNode") + `: ${currentName}`,
812
- {
813
- customClass: "rename-prompt",
814
- confirmButtonText: i18n.baseText("nodeView.prompt.rename"),
815
- cancelButtonText: i18n.baseText("nodeView.prompt.cancel"),
816
- inputErrorMessage: i18n.baseText("nodeView.prompt.invalidName"),
817
- inputValue: currentName,
818
- inputValidator: (value) => {
819
- if (!value.trim()) {
820
- return i18n.baseText("nodeView.prompt.invalidName");
821
- }
822
- return true;
823
- }
824
- }
825
- );
826
- await nextTick();
827
- const nameInput = document.querySelector(".rename-prompt .el-input__inner");
828
- nameInput?.focus();
829
- nameInput?.select();
830
- const promptResponse = await promptResponsePromise;
831
- if (promptResponse.action === MODAL_CONFIRM) {
832
- await renameNode(currentName, promptResponse.value, { trackHistory: true });
833
- }
834
- } catch (e) {
835
- }
836
- }
837
- async function onRevertRenameNode({
838
- currentName,
839
- newName
840
- }) {
841
- await revertRenameNode(currentName, newName);
842
- }
843
- function onUpdateNodeParameters(id, parameters) {
844
- setNodeParameters(id, parameters);
845
- }
846
- function onUpdateNodeInputs(id) {
847
- revalidateNodeInputConnections(id);
848
- }
849
- function onUpdateNodeOutputs(id) {
850
- revalidateNodeOutputConnections(id);
851
- }
852
- function onClickNodeAdd(source, sourceHandle) {
853
- nodeCreatorStore.openNodeCreatorForConnectingNode({
854
- connection: {
855
- source,
856
- sourceHandle
857
- },
858
- eventSource: NODE_CREATOR_OPEN_SOURCES.PLUS_ENDPOINT
859
- });
860
- }
861
- async function loadCredentials() {
862
- let options;
863
- if (workflowId.value) {
864
- options = { workflowId: workflowId.value };
865
- } else {
866
- const queryParam = typeof route.query?.projectId === "string" ? route.query?.projectId : void 0;
867
- const projectId = queryParam ?? projectsStore.personalProject?.id;
868
- if (projectId === void 0) {
869
- throw new Error(
870
- "Could not find projectId in the query nor could I find the personal project in the project store"
871
- );
872
- }
873
- options = { projectId };
874
- }
875
- await credentialsStore.fetchAllCredentialsForWorkflow(options);
876
- }
877
- function onCreateConnection(connection) {
878
- createConnection(connection, { trackHistory: true });
879
- }
880
- function onRevertCreateConnection({ connection }) {
881
- revertCreateConnection(connection);
882
- }
883
- function onCreateConnectionCancelled(event, position, mouseEvent) {
884
- const preventDefault = (mouseEvent?.target).classList?.contains("clickable");
885
- if (preventDefault) {
886
- return;
887
- }
888
- uiStore.lastInteractedWithNodeId = event.nodeId;
889
- uiStore.lastInteractedWithNodeHandle = event.handleId;
890
- uiStore.lastCancelledConnectionPosition = [position.x, position.y];
891
- setTimeout(() => {
892
- if (!event.nodeId) return;
893
- nodeCreatorStore.openNodeCreatorForConnectingNode({
894
- connection: {
895
- source: event.nodeId,
896
- sourceHandle: event.handleId
897
- },
898
- eventSource: NODE_CREATOR_OPEN_SOURCES.NODE_CONNECTION_DROP
899
- });
900
- });
901
- }
902
- function onDeleteConnection(connection) {
903
- deleteConnection(connection, { trackHistory: true });
904
- }
905
- function onRevertDeleteConnection({ connection }) {
906
- revertDeleteConnection(connection);
907
- }
908
- async function importWorkflowExact({ workflow: workflowData }) {
909
- if (!workflowData.nodes || !workflowData.connections) {
910
- throw new Error("Invalid workflow object");
911
- }
912
- resetWorkspace();
913
- await initializeData();
914
- initializeWorkspace({
915
- ...workflowData,
916
- nodes: getNodesWithNormalizedPosition(workflowData.nodes)
917
- });
918
- fitView();
919
- }
920
- async function onImportWorkflowDataEvent(data) {
921
- const workflowData = data.data;
922
- await importWorkflowData(workflowData, "file");
923
- fitView();
924
- selectNodes(workflowData.nodes?.map((node) => node.id) ?? []);
925
- if (data.tidyUp) {
926
- setTimeout(() => {
927
- canvasEventBus.emit("tidyUp", { source: "import-workflow-data" });
928
- }, 0);
929
- }
930
- }
931
- async function onImportWorkflowUrlEvent(data) {
932
- const workflowData = await fetchWorkflowDataFromUrl(data.url);
933
- if (!workflowData) {
934
- return;
935
- }
936
- await importWorkflowData(workflowData, "url");
937
- fitView();
938
- selectNodes(workflowData.nodes?.map((node) => node.id) ?? []);
939
- }
940
- function addImportEventBindings() {
941
- nodeViewEventBus.on("importWorkflowData", onImportWorkflowDataEvent);
942
- nodeViewEventBus.on("importWorkflowUrl", onImportWorkflowUrlEvent);
943
- nodeViewEventBus.on("openChat", onOpenChat);
944
- }
945
- function removeImportEventBindings() {
946
- nodeViewEventBus.off("importWorkflowData", onImportWorkflowDataEvent);
947
- nodeViewEventBus.off("importWorkflowUrl", onImportWorkflowUrlEvent);
948
- nodeViewEventBus.off("openChat", onOpenChat);
949
- }
950
- async function onAddNodesAndConnections({ nodes, connections }, dragAndDrop = false, position) {
951
- if (!checkIfEditingIsAllowed()) {
952
- return;
953
- }
954
- const addedNodes = await addNodes(nodes, {
955
- dragAndDrop,
956
- position,
957
- trackHistory: true,
958
- telemetry: true
959
- });
960
- const offsetIndex = editableWorkflow.value.nodes.length - nodes.length;
961
- const mappedConnections = connections.map(({ from, to }) => {
962
- const fromNode = editableWorkflow.value.nodes[offsetIndex + from.nodeIndex];
963
- const toNode = editableWorkflow.value.nodes[offsetIndex + to.nodeIndex];
964
- const type = from.type ?? to.type ?? NodeConnectionTypes.Main;
965
- return {
966
- source: fromNode.id,
967
- sourceHandle: createCanvasConnectionHandleString({
968
- mode: CanvasConnectionMode.Output,
969
- type: isValidNodeConnectionType(type) ? type : NodeConnectionTypes.Main,
970
- index: from.outputIndex ?? 0
971
- }),
972
- target: toNode.id,
973
- targetHandle: createCanvasConnectionHandleString({
974
- mode: CanvasConnectionMode.Input,
975
- type: isValidNodeConnectionType(type) ? type : NodeConnectionTypes.Main,
976
- index: to.inputIndex ?? 0
977
- }),
978
- data: {
979
- source: {
980
- index: from.outputIndex ?? 0,
981
- type
982
- },
983
- target: {
984
- index: to.inputIndex ?? 0,
985
- type
986
- }
987
- }
988
- };
989
- });
990
- await addConnections(mappedConnections);
991
- uiStore.resetLastInteractedWith();
992
- if (addedNodes.length > 0) {
993
- selectNodes([addedNodes[addedNodes.length - 1].id]);
994
- }
995
- }
996
- async function onRevertAddNode({ node }) {
997
- await revertAddNode(node.name);
998
- }
999
- async function onSwitchActiveNode(nodeName) {
1000
- const node = workflowsStore.getNodeByName(nodeName);
1001
- if (!node) return;
1002
- setNodeActiveByName(nodeName);
1003
- selectNodes([node.id]);
1004
- }
1005
- async function onOpenSelectiveNodeCreator(node, connectionType) {
1006
- nodeCreatorStore.openSelectiveNodeCreator({ node, connectionType });
1007
- }
1008
- async function onOpenNodeCreatorForTriggerNodes(source) {
1009
- nodeCreatorStore.openNodeCreatorForTriggerNodes(source);
1010
- }
1011
- function onOpenNodeCreatorFromCanvas(source) {
1012
- onToggleNodeCreator({ createNodeActive: true, source });
1013
- }
1014
- function onToggleNodeCreator(options) {
1015
- nodeCreatorStore.setNodeCreatorState(options);
1016
- if (!options.createNodeActive && !options.hasAddedNodes) {
1017
- uiStore.resetLastInteractedWith();
1018
- }
1019
- }
1020
- function closeNodeCreator() {
1021
- if (nodeCreatorStore.isCreateNodeActive) {
1022
- nodeCreatorStore.isCreateNodeActive = false;
1023
- }
1024
- }
1025
- function onCreateSticky() {
1026
- void onAddNodesAndConnections({ nodes: [{ type: STICKY_NODE_TYPE }], connections: [] });
1027
- }
1028
- function onClickConnectionAdd(connection) {
1029
- nodeCreatorStore.openNodeCreatorForConnectingNode({
1030
- connection,
1031
- eventSource: NODE_CREATOR_OPEN_SOURCES.NODE_CONNECTION_ACTION
1032
- });
1033
- }
1034
- const workflowPermissions = computed(() => {
1035
- return workflowId.value ? getResourcePermissions(workflowsStore.getWorkflowById(workflowId.value)?.scopes).workflow : {};
1036
- });
1037
- const projectPermissions = computed(() => {
1038
- const project = route.query?.projectId ? projectsStore.myProjects.find((p) => p.id === route.query.projectId) : projectsStore.currentProject ?? projectsStore.personalProject;
1039
- return getResourcePermissions(project?.scopes);
1040
- });
1041
- const isStoppingExecution = ref(false);
1042
- const isWorkflowRunning = computed(() => workflowsStore.isWorkflowRunning);
1043
- const isExecutionWaitingForWebhook = computed(() => workflowsStore.executionWaitingForWebhook);
1044
- const isExecutionDisabled = computed(() => {
1045
- if (containsChatTriggerNodes.value && isOnlyChatTriggerNodeActive.value && !chatTriggerNodePinnedData.value) {
1046
- return true;
1047
- }
1048
- return !containsTriggerNodes.value || allTriggerNodesDisabled.value;
1049
- });
1050
- const isRunWorkflowButtonVisible = computed(
1051
- () => !isOnlyChatTriggerNodeActive.value || chatTriggerNodePinnedData.value
1052
- );
1053
- const isStopExecutionButtonVisible = computed(
1054
- () => isWorkflowRunning.value && !isExecutionWaitingForWebhook.value
1055
- );
1056
- const isStopWaitingForWebhookButtonVisible = computed(
1057
- () => isWorkflowRunning.value && isExecutionWaitingForWebhook.value
1058
- );
1059
- const isClearExecutionButtonVisible = useClearExecutionButtonVisible();
1060
- async function onRunWorkflowToNode(id) {
1061
- const node = workflowsStore.getNodeById(id);
1062
- if (!node) return;
1063
- if (needsAgentInput(node) && nodeTypesStore.isToolNode(node.type)) {
1064
- uiStore.openModalWithData({
1065
- name: FROM_AI_PARAMETERS_MODAL_KEY,
1066
- data: {
1067
- nodeName: node.name
1068
- }
1069
- });
1070
- } else {
1071
- trackRunWorkflowToNode(node);
1072
- agentRequestStore.clearAgentRequests(workflowsStore.workflowId, node.id);
1073
- void runWorkflow({ destinationNode: node.name, source: "Node.executeNode" });
1074
- }
1075
- }
1076
- function trackRunWorkflowToNode(node) {
1077
- const telemetryPayload = {
1078
- node_type: node.type,
1079
- workflow_id: workflowsStore.workflowId,
1080
- source: "canvas",
1081
- push_ref: ndvStore.pushRef
1082
- };
1083
- telemetry.track("User clicked execute node button", telemetryPayload);
1084
- void externalHooks.run("nodeView.onRunNode", telemetryPayload);
1085
- }
1086
- async function onOpenExecution(executionId) {
1087
- canvasStore.startLoading();
1088
- resetWorkspace();
1089
- await initializeData();
1090
- const data = await openExecution(executionId);
1091
- if (!data) {
1092
- return;
1093
- }
1094
- void nextTick(() => {
1095
- updateNodesIssues();
1096
- });
1097
- canvasStore.stopLoading();
1098
- fitView();
1099
- canvasEventBus.emit("open:execution", data);
1100
- void externalHooks.run("execution.open", {
1101
- workflowId: data.workflowData.id,
1102
- workflowName: data.workflowData.name,
1103
- executionId
1104
- });
1105
- telemetry.track("User opened read-only execution", {
1106
- workflow_id: data.workflowData.id,
1107
- execution_mode: data.mode,
1108
- execution_finished: data.finished
1109
- });
1110
- }
1111
- function onExecutionOpenedWithError(data) {
1112
- if (!data.finished && data.data?.resultData?.error) {
1113
- let nodeErrorFound = false;
1114
- if (data.data.resultData.runData) {
1115
- const runData = data.data.resultData.runData;
1116
- errorCheck: for (const nodeName of Object.keys(runData)) {
1117
- for (const taskData of runData[nodeName]) {
1118
- if (taskData.error) {
1119
- nodeErrorFound = true;
1120
- break errorCheck;
1121
- }
1122
- }
1123
- }
1124
- }
1125
- if (!nodeErrorFound && (data.data.resultData.error.stack ?? data.data.resultData.error.message)) {
1126
- console.error(`Execution ${data.id} error:`);
1127
- console.error(data.data.resultData.error.stack);
1128
- toast.showMessage({
1129
- title: i18n.baseText("nodeView.showError.workflowError"),
1130
- message: data.data.resultData.error.message,
1131
- type: "error",
1132
- duration: 0
1133
- });
1134
- }
1135
- }
1136
- }
1137
- function onExecutionOpenedWithWaitTill(data) {
1138
- if (data.waitTill) {
1139
- toast.showMessage({
1140
- title: i18n.baseText("nodeView.thisExecutionHasntFinishedYet"),
1141
- message: h(_sfc_main$1),
1142
- type: "warning",
1143
- duration: 0
1144
- });
1145
- }
1146
- }
1147
- function addExecutionOpenedEventBindings() {
1148
- canvasEventBus.on("open:execution", onExecutionOpenedWithError);
1149
- canvasEventBus.on("open:execution", onExecutionOpenedWithWaitTill);
1150
- }
1151
- function removeExecutionOpenedEventBindings() {
1152
- canvasEventBus.off("open:execution", onExecutionOpenedWithError);
1153
- canvasEventBus.off("open:execution", onExecutionOpenedWithWaitTill);
1154
- }
1155
- async function onStopExecution() {
1156
- isStoppingExecution.value = true;
1157
- await stopCurrentExecution();
1158
- isStoppingExecution.value = false;
1159
- }
1160
- async function onStopWaitingForWebhook() {
1161
- await stopWaitingForWebhook();
1162
- }
1163
- async function onClearExecutionData() {
1164
- workflowsStore.workflowExecutionData = null;
1165
- nodeHelpers.updateNodesExecutionIssues();
1166
- }
1167
- function onRunWorkflowButtonMouseEnter() {
1168
- nodeViewEventBus.emit("runWorkflowButton:mouseenter");
1169
- }
1170
- function onRunWorkflowButtonMouseLeave() {
1171
- nodeViewEventBus.emit("runWorkflowButton:mouseleave");
1172
- }
1173
- const chatTriggerNode = computed(() => {
1174
- return editableWorkflow.value.nodes.find((node) => node.type === CHAT_TRIGGER_NODE_TYPE);
1175
- });
1176
- const containsChatTriggerNodes = computed(() => {
1177
- return !isExecutionWaitingForWebhook.value && !!editableWorkflow.value.nodes.find(
1178
- (node) => [MANUAL_CHAT_TRIGGER_NODE_TYPE, CHAT_TRIGGER_NODE_TYPE].includes(node.type) && node.disabled !== true
1179
- );
1180
- });
1181
- const isOnlyChatTriggerNodeActive = computed(() => {
1182
- return triggerNodes.value.every((node) => node.disabled || node.type === CHAT_TRIGGER_NODE_TYPE);
1183
- });
1184
- const chatTriggerNodePinnedData = computed(() => {
1185
- if (!chatTriggerNode.value) return null;
1186
- return workflowsStore.pinDataByNodeName(chatTriggerNode.value.name);
1187
- });
1188
- async function onToggleChat() {
1189
- await toggleChatOpen("main");
1190
- }
1191
- async function onOpenChat() {
1192
- await toggleChatOpen("main", true);
1193
- }
1194
- function addUndoRedoEventBindings() {
1195
- historyBus.on("nodeMove", onRevertNodePosition);
1196
- historyBus.on("revertAddNode", onRevertAddNode);
1197
- historyBus.on("revertRemoveNode", onRevertDeleteNode);
1198
- historyBus.on("revertAddConnection", onRevertCreateConnection);
1199
- historyBus.on("revertRemoveConnection", onRevertDeleteConnection);
1200
- historyBus.on("revertRenameNode", onRevertRenameNode);
1201
- historyBus.on("enableNodeToggle", onRevertToggleNodeDisabled);
1202
- }
1203
- function removeUndoRedoEventBindings() {
1204
- historyBus.off("nodeMove", onRevertNodePosition);
1205
- historyBus.off("revertAddNode", onRevertAddNode);
1206
- historyBus.off("revertRemoveNode", onRevertDeleteNode);
1207
- historyBus.off("revertAddConnection", onRevertCreateConnection);
1208
- historyBus.off("revertRemoveConnection", onRevertDeleteConnection);
1209
- historyBus.off("revertRenameNode", onRevertRenameNode);
1210
- historyBus.off("enableNodeToggle", onRevertToggleNodeDisabled);
1211
- }
1212
- async function onSourceControlPull() {
1213
- try {
1214
- await Promise.all([
1215
- environmentsStore.fetchAllVariables(),
1216
- tagsStore.fetchAll(),
1217
- loadCredentials()
1218
- ]);
1219
- if (workflowId.value && !uiStore.stateIsDirty) {
1220
- const workflowData = await workflowsStore.fetchWorkflow(workflowId.value);
1221
- if (workflowData) {
1222
- workflowHelpers.setDocumentTitle(workflowData.name, "IDLE");
1223
- openWorkflow(workflowData);
1224
- }
1225
- }
1226
- } catch (error) {
1227
- console.error(error);
1228
- }
1229
- }
1230
- function addSourceControlEventBindings() {
1231
- sourceControlEventBus.on("pull", onSourceControlPull);
1232
- }
1233
- function removeSourceControlEventBindings() {
1234
- sourceControlEventBus.off("pull", onSourceControlPull);
1235
- }
1236
- function addPostMessageEventBindings() {
1237
- window.addEventListener("message", onPostMessageReceived);
1238
- }
1239
- function removePostMessageEventBindings() {
1240
- window.removeEventListener("message", onPostMessageReceived);
1241
- }
1242
- function emitPostMessageReady() {
1243
- if (window.parent) {
1244
- window.parent.postMessage(
1245
- JSON.stringify({ command: "n8nReady", version: rootStore.versionCli }),
1246
- "*"
1247
- );
1248
- }
1249
- }
1250
- async function onPostMessageReceived(messageEvent) {
1251
- if (!messageEvent || typeof messageEvent.data !== "string" || !messageEvent.data?.includes?.('"command"')) {
1252
- return;
1253
- }
1254
- try {
1255
- const json = JSON.parse(messageEvent.data);
1256
- if (json && json.command === "openWorkflow") {
1257
- try {
1258
- await importWorkflowExact(json);
1259
- canOpenNDV.value = json.canOpenNDV ?? true;
1260
- hideNodeIssues.value = json.hideNodeIssues ?? false;
1261
- isExecutionPreview.value = false;
1262
- } catch (e) {
1263
- if (window.top) {
1264
- window.top.postMessage(
1265
- JSON.stringify({
1266
- command: "error",
1267
- message: i18n.baseText("openWorkflow.workflowImportError")
1268
- }),
1269
- "*"
1270
- );
1271
- }
1272
- toast.showError(e, i18n.baseText("openWorkflow.workflowImportError"));
1273
- }
1274
- } else if (json && json.command === "openExecution") {
1275
- try {
1276
- isProductionExecutionPreview.value = json.executionMode !== "manual" && json.executionMode !== "evaluation";
1277
- await onOpenExecution(json.executionId);
1278
- canOpenNDV.value = json.canOpenNDV ?? true;
1279
- hideNodeIssues.value = json.hideNodeIssues ?? false;
1280
- isExecutionPreview.value = true;
1281
- } catch (e) {
1282
- if (window.top) {
1283
- window.top.postMessage(
1284
- JSON.stringify({
1285
- command: "error",
1286
- message: i18n.baseText("nodeView.showError.openExecution.title")
1287
- }),
1288
- "*"
1289
- );
1290
- }
1291
- toast.showMessage({
1292
- title: i18n.baseText("nodeView.showError.openExecution.title"),
1293
- message: e.message,
1294
- type: "error"
1295
- });
1296
- }
1297
- } else if (json?.command === "setActiveExecution") {
1298
- executionsStore.activeExecution = await executionsStore.fetchExecution(
1299
- json.executionId
1300
- );
1301
- }
1302
- } catch (e) {
1303
- }
1304
- }
1305
- function checkIfEditingIsAllowed() {
1306
- if (!initializedWorkflowId.value) {
1307
- return true;
1308
- }
1309
- if (readOnlyNotification.value?.visible) {
1310
- return false;
1311
- }
1312
- if (isReadOnlyRoute.value || isReadOnlyEnvironment.value) {
1313
- const messageContext = isReadOnlyRoute.value ? "executions" : "workflows";
1314
- readOnlyNotification.value = toast.showMessage({
1315
- title: i18n.baseText(
1316
- isReadOnlyEnvironment.value ? `readOnlyEnv.showMessage.${messageContext}.title` : "readOnly.showMessage.executions.title"
1317
- ),
1318
- message: i18n.baseText(
1319
- isReadOnlyEnvironment.value ? `readOnlyEnv.showMessage.${messageContext}.message` : "readOnly.showMessage.executions.message"
1320
- ),
1321
- type: "info"
1322
- });
1323
- return false;
1324
- }
1325
- return true;
1326
- }
1327
- function checkIfRouteIsAllowed() {
1328
- if (isReadOnlyEnvironment.value && [VIEWS.NEW_WORKFLOW, VIEWS.TEMPLATE_IMPORT].find((view) => view === route.name)) {
1329
- void nextTick(async () => {
1330
- resetWorkspace();
1331
- uiStore.stateIsDirty = false;
1332
- await router.replace({ name: VIEWS.HOMEPAGE });
1333
- });
1334
- }
1335
- }
1336
- async function initializeDebugMode() {
1337
- workflowHelpers.setDocumentTitle(workflowsStore.workflowName, "DEBUG");
1338
- if (!workflowsStore.isInDebugMode) {
1339
- await applyExecutionData(route.params.executionId);
1340
- workflowsStore.isInDebugMode = true;
1341
- }
1342
- canvasEventBus.on("saved:workflow", onSaveFromWithinExecutionDebug);
1343
- }
1344
- async function onSaveFromWithinExecutionDebug() {
1345
- if (route.name !== VIEWS.EXECUTION_DEBUG) return;
1346
- await router.replace({
1347
- name: VIEWS.WORKFLOW,
1348
- params: { name: workflowId.value }
1349
- });
1350
- }
1351
- const viewportTransform = ref({ x: 0, y: 0, zoom: 1 });
1352
- function onViewportChange(event) {
1353
- viewportTransform.value = event;
1354
- uiStore.nodeViewOffsetPosition = [event.x, event.y];
1355
- }
1356
- function fitView() {
1357
- setTimeout(() => canvasEventBus.emit("fitView"));
1358
- }
1359
- function selectNodes(ids) {
1360
- setTimeout(() => canvasEventBus.emit("nodes:select", { ids }));
1361
- }
1362
- function onClickPane(position) {
1363
- lastClickPosition.value = [position.x, position.y];
1364
- onSetNodeSelected();
1365
- }
1366
- async function onDragAndDrop(position, event) {
1367
- if (!event.dataTransfer) {
1368
- return;
1369
- }
1370
- const dropData = jsonParse(
1371
- event.dataTransfer.getData(DRAG_EVENT_DATA_KEY)
1372
- );
1373
- if (dropData) {
1374
- const insertNodePosition = [position.x, position.y];
1375
- await onAddNodesAndConnections(dropData, true, insertNodePosition);
1376
- onToggleNodeCreator({ createNodeActive: false, hasAddedNodes: true });
1377
- }
1378
- }
1379
- function registerCustomActions() {
1380
- registerCustomAction({
1381
- key: "openNodeDetail",
1382
- action: ({ node }) => {
1383
- setNodeActiveByName(node);
1384
- }
1385
- });
1386
- registerCustomAction({
1387
- key: "openSelectiveNodeCreator",
1388
- action: ({
1389
- creatorview: creatorView,
1390
- connectiontype: connectionType,
1391
- node
1392
- }) => {
1393
- nodeCreatorStore.openSelectiveNodeCreator({ node, connectionType, creatorView });
1394
- }
1395
- });
1396
- registerCustomAction({
1397
- key: "showNodeCreator",
1398
- action: () => {
1399
- ndvStore.activeNodeName = null;
1400
- void nextTick(() => {
1401
- void onOpenNodeCreatorForTriggerNodes(NODE_CREATOR_OPEN_SOURCES.TAB);
1402
- });
1403
- }
1404
- });
1405
- }
1406
- function unregisterCustomActions() {
1407
- unregisterCustomAction("openNodeDetail");
1408
- unregisterCustomAction("openSelectiveNodeCreator");
1409
- unregisterCustomAction("showNodeCreator");
1410
- }
1411
- function showAddFirstStepIfEnabled() {
1412
- if (uiStore.addFirstStepOnLoad) {
1413
- void onOpenNodeCreatorForTriggerNodes(NODE_CREATOR_OPEN_SOURCES.TRIGGER_PLACEHOLDER_BUTTON);
1414
- uiStore.addFirstStepOnLoad = false;
1415
- }
1416
- }
1417
- function updateNodeRoute(nodeId) {
1418
- const nodeUi = workflowsStore.findNodeByPartialId(nodeId);
1419
- if (nodeUi) {
1420
- setNodeActive(nodeUi.id);
1421
- } else {
1422
- toast.showToast({
1423
- title: i18n.baseText("nodeView.showMessage.ndvUrl.missingNodes.title"),
1424
- message: i18n.baseText("nodeView.showMessage.ndvUrl.missingNodes.content"),
1425
- type: "warning"
1426
- });
1427
- void router.replace({
1428
- name: route.name,
1429
- params: { name: workflowId.value }
1430
- });
1431
- }
1432
- }
1433
- watch(
1434
- () => route.name,
1435
- async (newRouteName, oldRouteName) => {
1436
- const force = newRouteName === VIEWS.NEW_WORKFLOW && oldRouteName === VIEWS.WORKFLOW || newRouteName === VIEWS.WORKFLOW && oldRouteName === VIEWS.NEW_WORKFLOW;
1437
- await initializeRoute(force);
1438
- }
1439
- );
1440
- watch(
1441
- () => {
1442
- return isLoading.value || isCanvasReadOnly.value || editableWorkflow.value.nodes.length !== 0;
1443
- },
1444
- (isReadOnlyOrLoading) => {
1445
- const defaultFallbackNodes = [
1446
- {
1447
- id: CanvasNodeRenderType.AddNodes,
1448
- name: CanvasNodeRenderType.AddNodes,
1449
- type: CanvasNodeRenderType.AddNodes,
1450
- typeVersion: 1,
1451
- position: [0, 0],
1452
- parameters: {}
1453
- }
1454
- ];
1455
- if (builderStore.isAIBuilderEnabled && builderStore.isAssistantEnabled) {
1456
- defaultFallbackNodes.unshift({
1457
- id: CanvasNodeRenderType.AIPrompt,
1458
- name: CanvasNodeRenderType.AIPrompt,
1459
- type: CanvasNodeRenderType.AIPrompt,
1460
- typeVersion: 1,
1461
- position: [-690, -15],
1462
- parameters: {}
1463
- });
1464
- }
1465
- fallbackNodes.value = isReadOnlyOrLoading ? [] : defaultFallbackNodes;
1466
- }
1467
- );
1468
- watch(
1469
- () => route.params.nodeId,
1470
- async (newId) => {
1471
- if (typeof newId !== "string" || newId === "") ndvStore.activeNodeName = null;
1472
- else {
1473
- updateNodeRoute(newId);
1474
- }
1475
- }
1476
- );
1477
- watch(
1478
- () => ndvStore.activeNode,
1479
- async (val) => {
1480
- if (![VIEWS.WORKFLOW].includes(String(route.name))) return;
1481
- const nodeId = val?.id ? workflowsStore.getPartialIdForNode(val?.id) : "";
1482
- if (nodeId !== route.params.nodeId) {
1483
- await router.replace({
1484
- name: route.name,
1485
- params: { name: workflowId.value, nodeId }
1486
- });
1487
- }
1488
- }
1489
- );
1490
- onBeforeRouteLeave(async (to, from, next) => {
1491
- const toNodeViewTab = getNodeViewTab(to);
1492
- if (toNodeViewTab === MAIN_HEADER_TABS.EXECUTIONS || from.name === VIEWS.TEMPLATE_IMPORT || toNodeViewTab === MAIN_HEADER_TABS.WORKFLOW && from.name === VIEWS.EXECUTION_DEBUG || isReadOnlyEnvironment.value) {
1493
- next();
1494
- return;
1495
- }
1496
- await useWorkflowSaving({ router }).promptSaveUnsavedWorkflowChanges(next, {
1497
- async confirm() {
1498
- if (from.name === VIEWS.NEW_WORKFLOW) {
1499
- const savedWorkflowId = workflowsStore.workflowId;
1500
- await router.replace({
1501
- name: VIEWS.WORKFLOW,
1502
- params: { name: savedWorkflowId }
1503
- });
1504
- await router.push(to);
1505
- return false;
1506
- }
1507
- workflowsStore.setWorkflowId(PLACEHOLDER_EMPTY_WORKFLOW_ID);
1508
- return true;
1509
- }
1510
- });
1511
- });
1512
- onBeforeMount(() => {
1513
- if (!isDemoRoute.value) {
1514
- pushConnectionStore.pushConnect();
1515
- }
1516
- addPostMessageEventBindings();
1517
- });
1518
- onMounted(() => {
1519
- canvasStore.startLoading();
1520
- documentTitle.reset();
1521
- resetWorkspace();
1522
- void initializeData().then(() => {
1523
- void initializeRoute().then(() => {
1524
- toast.showNotificationForViews([VIEWS.WORKFLOW, VIEWS.NEW_WORKFLOW]);
1525
- if (route.query.settings) {
1526
- uiStore.openModal(WORKFLOW_SETTINGS_MODAL_KEY);
1527
- void router.replace({ query: { settings: void 0 } });
1528
- }
1529
- }).finally(() => {
1530
- isLoading.value = false;
1531
- canvasStore.stopLoading();
1532
- void externalHooks.run("nodeView.mount").catch(() => {
1533
- });
1534
- setTimeout(() => {
1535
- if (routeNodeId.value) {
1536
- updateNodeRoute(routeNodeId.value);
1537
- }
1538
- }, 500);
1539
- emitPostMessageReady();
1540
- });
1541
- void usersStore.showPersonalizationSurvey();
1542
- checkIfRouteIsAllowed();
1543
- });
1544
- addSourceControlEventBindings();
1545
- addWorkflowSavedEventBindings();
1546
- addBeforeUnloadEventBindings();
1547
- addImportEventBindings();
1548
- addExecutionOpenedEventBindings();
1549
- registerCustomActions();
1550
- });
1551
- onActivated(async () => {
1552
- addUndoRedoEventBindings();
1553
- showAddFirstStepIfEnabled();
1554
- });
1555
- onDeactivated(() => {
1556
- removeUndoRedoEventBindings();
1557
- });
1558
- onBeforeUnmount(() => {
1559
- removeSourceControlEventBindings();
1560
- removePostMessageEventBindings();
1561
- removeWorkflowSavedEventBindings();
1562
- removeBeforeUnloadEventBindings();
1563
- removeImportEventBindings();
1564
- removeExecutionOpenedEventBindings();
1565
- unregisterCustomActions();
1566
- if (!isDemoRoute.value) {
1567
- pushConnectionStore.pushDisconnect();
1568
- }
1569
- });
1570
- return (_ctx, _cache) => {
1571
- const _component_CanvasChatButton = _sfc_main$7;
1572
- return unref(editableWorkflow) && unref(editableWorkflowObject) && !isLoading.value ? (openBlock(), createBlock(WorkflowCanvas, {
1573
- key: 0,
1574
- id: unref(editableWorkflow).id,
1575
- workflow: unref(editableWorkflow),
1576
- "workflow-object": unref(editableWorkflowObject),
1577
- "fallback-nodes": fallbackNodes.value,
1578
- "show-fallback-nodes": showFallbackNodes.value,
1579
- "event-bus": unref(canvasEventBus),
1580
- "read-only": isCanvasReadOnly.value,
1581
- executing: isWorkflowRunning.value,
1582
- "key-bindings": keyBindingsEnabled.value,
1583
- "onUpdate:nodes:position": onUpdateNodesPosition,
1584
- "onUpdate:node:position": onUpdateNodePosition,
1585
- "onUpdate:node:activated": onSetNodeActivated,
1586
- "onUpdate:node:deactivated": onSetNodeDeactivated,
1587
- "onUpdate:node:selected": onSetNodeSelected,
1588
- "onUpdate:node:enabled": onToggleNodeDisabled,
1589
- "onUpdate:node:name": onOpenRenameNodeModal,
1590
- "onUpdate:node:parameters": onUpdateNodeParameters,
1591
- "onUpdate:node:inputs": onUpdateNodeInputs,
1592
- "onUpdate:node:outputs": onUpdateNodeOutputs,
1593
- "onOpen:subWorkflow": onOpenSubWorkflow,
1594
- "onClick:node": onClickNode,
1595
- "onClick:node:add": onClickNodeAdd,
1596
- "onRun:node": onRunWorkflowToNode,
1597
- "onDelete:node": onDeleteNode,
1598
- "onCreate:connection": onCreateConnection,
1599
- "onCreate:connection:cancelled": onCreateConnectionCancelled,
1600
- "onDelete:connection": onDeleteConnection,
1601
- "onClick:connection:add": onClickConnectionAdd,
1602
- "onClick:pane": onClickPane,
1603
- "onCreate:node": onOpenNodeCreatorFromCanvas,
1604
- "onCreate:sticky": onCreateSticky,
1605
- "onDelete:nodes": onDeleteNodes,
1606
- "onUpdate:nodes:enabled": onToggleNodesDisabled,
1607
- "onUpdate:nodes:pin": onPinNodes,
1608
- "onDuplicate:nodes": onDuplicateNodes,
1609
- "onCopy:nodes": onCopyNodes,
1610
- "onCut:nodes": onCutNodes,
1611
- "onRun:workflow": _cache[1] || (_cache[1] = ($event) => unref(runEntireWorkflow)("main")),
1612
- "onSave:workflow": onSaveWorkflow,
1613
- "onCreate:workflow": onCreateWorkflow,
1614
- onViewportChange,
1615
- onDragAndDrop,
1616
- onTidyUp
1617
- }, {
1618
- default: withCtx(() => [
1619
- (openBlock(), createBlock(Suspense, null, {
1620
- default: withCtx(() => [
1621
- createVNode(unref(LazySetupWorkflowCredentialsButton), {
1622
- class: normalizeClass(unref($style).setupCredentialsButtonWrapper)
1623
- }, null, 8, ["class"])
1624
- ]),
1625
- _: 1
1626
- })),
1627
- !isCanvasReadOnly.value ? (openBlock(), createElementBlock("div", {
1628
- key: 0,
1629
- class: normalizeClass(unref($style).executionButtons)
1630
- }, [
1631
- isRunWorkflowButtonVisible.value ? (openBlock(), createBlock(_sfc_main$5, {
1632
- key: 0,
1633
- "waiting-for-webhook": isExecutionWaitingForWebhook.value,
1634
- disabled: isExecutionDisabled.value,
1635
- executing: isWorkflowRunning.value,
1636
- onMouseenter: onRunWorkflowButtonMouseEnter,
1637
- onMouseleave: onRunWorkflowButtonMouseLeave,
1638
- onClick: _cache[0] || (_cache[0] = ($event) => unref(runEntireWorkflow)("main"))
1639
- }, null, 8, ["waiting-for-webhook", "disabled", "executing"])) : createCommentVNode("", true),
1640
- containsChatTriggerNodes.value ? (openBlock(), createBlock(_component_CanvasChatButton, {
1641
- key: 1,
1642
- type: isLogsPanelOpen.value ? "tertiary" : "primary",
1643
- label: isLogsPanelOpen.value ? unref(i18n).baseText("chat.hide") : unref(i18n).baseText("chat.open"),
1644
- onClick: onToggleChat
1645
- }, null, 8, ["type", "label"])) : createCommentVNode("", true),
1646
- isStopExecutionButtonVisible.value ? (openBlock(), createBlock(_sfc_main$4, {
1647
- key: 2,
1648
- stopping: isStoppingExecution.value,
1649
- onClick: onStopExecution
1650
- }, null, 8, ["stopping"])) : createCommentVNode("", true),
1651
- isStopWaitingForWebhookButtonVisible.value ? (openBlock(), createBlock(_sfc_main$3, {
1652
- key: 3,
1653
- onClick: onStopWaitingForWebhook
1654
- })) : createCommentVNode("", true),
1655
- unref(isClearExecutionButtonVisible) && !unref(settingsStore).isNewLogsEnabled ? (openBlock(), createBlock(_sfc_main$2, {
1656
- key: 4,
1657
- onClick: onClearExecutionData
1658
- })) : createCommentVNode("", true)
1659
- ], 2)) : createCommentVNode("", true),
1660
- isReadOnlyEnvironment.value ? (openBlock(), createBlock(unref(N8nCallout), {
1661
- key: 1,
1662
- theme: "warning",
1663
- icon: "lock",
1664
- class: normalizeClass(unref($style).readOnlyEnvironmentNotification)
1665
- }, {
1666
- default: withCtx(() => [
1667
- createTextVNode(toDisplayString(unref(i18n).baseText("readOnlyEnv.cantEditOrRun")), 1)
1668
- ]),
1669
- _: 1
1670
- }, 8, ["class"])) : createCommentVNode("", true),
1671
- (openBlock(), createBlock(Suspense, null, {
1672
- default: withCtx(() => [
1673
- !isCanvasReadOnly.value ? (openBlock(), createBlock(unref(LazyNodeCreation), {
1674
- key: 0,
1675
- "create-node-active": unref(nodeCreatorStore).isCreateNodeActive,
1676
- "node-view-scale": viewportTransform.value.zoom,
1677
- onToggleNodeCreator,
1678
- onAddNodes: onAddNodesAndConnections
1679
- }, null, 8, ["create-node-active", "node-view-scale"])) : createCommentVNode("", true)
1680
- ]),
1681
- _: 1
1682
- })),
1683
- (openBlock(), createBlock(Suspense, null, {
1684
- default: withCtx(() => [
1685
- createVNode(unref(LazyNodeDetailsView), {
1686
- "workflow-object": unref(editableWorkflowObject),
1687
- "read-only": isCanvasReadOnly.value,
1688
- "is-production-execution-preview": isProductionExecutionPreview.value,
1689
- renaming: false,
1690
- onValueChanged: onRenameNode,
1691
- onStopExecution,
1692
- onSwitchSelectedNode: onSwitchActiveNode,
1693
- onOpenConnectionNodeCreator: onOpenSelectiveNodeCreator,
1694
- onSaveKeyboardShortcut: onSaveWorkflow
1695
- }, null, 8, ["workflow-object", "read-only", "is-production-execution-preview"])
1696
- ]),
1697
- _: 1
1698
- }))
1699
- ]),
1700
- _: 1
1701
- }, 8, ["id", "workflow", "workflow-object", "fallback-nodes", "show-fallback-nodes", "event-bus", "read-only", "executing", "key-bindings"])) : createCommentVNode("", true);
1702
- };
1703
- }
1704
- });
1705
- const executionButtons = "_executionButtons_8gz1l_123";
1706
- const setupCredentialsButtonWrapper = "_setupCredentialsButtonWrapper_8gz1l_161";
1707
- const readOnlyEnvironmentNotification = "_readOnlyEnvironmentNotification_8gz1l_167";
1708
- const style0 = {
1709
- executionButtons,
1710
- setupCredentialsButtonWrapper,
1711
- readOnlyEnvironmentNotification
1712
- };
1713
- const cssModules = {
1714
- "$style": style0
1715
- };
1716
- const NodeView = /* @__PURE__ */ _export_sfc(_sfc_main, [["__cssModules", cssModules]]);
1717
- export {
1718
- NodeView as default
1719
- };