n8n-editor-ui 1.94.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 (118) hide show
  1. package/dist/assets/{AnimatedSpinner-CY5xYI5m.js → AnimatedSpinner-DlBYfeum.js} +1 -1
  2. package/dist/assets/{AnnotationTagsDropdown.ee.vue_vue_type_script_setup_true_lang-BOrzkwPH.js → AnnotationTagsDropdown.ee.vue_vue_type_script_setup_true_lang-b_VpBPcV.js} +1 -1
  3. package/dist/assets/{AuthView-BTzGYAnY.js → AuthView-3BmNl_WD.js} +2 -2
  4. package/dist/assets/{CanvasChatSwitch-CwpjFCL0.js → CanvasChatSwitch-C8GVNbZv.js} +8 -9
  5. package/dist/assets/{ChangePasswordView-BKR2UFVI.js → ChangePasswordView-HptU1MSc.js} +3 -3
  6. package/dist/assets/CollectionParameter-DB_Or-wG.js +4 -0
  7. package/dist/assets/{CredentialsView-DVgxfnNi.js → CredentialsView-Dx5hgaaC.js} +7 -7
  8. package/dist/assets/{DemoFooter-C1T3Q0NX.js → DemoFooter-BkSVK4cp.js} +6 -7
  9. package/dist/assets/{ErrorView-Cf2Yb8Ea.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-DUu0UMcW.js → ExecutionsTime.vue_vue_type_script_setup_true_lang-BioZloew.js} +2 -2
  15. package/dist/assets/{ExecutionsView-DjNkfnDh.js → ExecutionsView-SVk21vMq.js} +8 -9
  16. package/dist/assets/{FileSaver.min-C1p9Eies.js → FileSaver.min-ZbRn_Jz1.js} +1 -1
  17. package/dist/assets/{FixedCollectionParameter-DN_uJhpe.js → FixedCollectionParameter-iCfhPCTX.js} +1 -1
  18. package/dist/assets/{ForgotMyPasswordView-BMQBDIrq.js → ForgotMyPasswordView-DID5un7M.js} +3 -3
  19. package/dist/assets/{InsightsChartAverageRuntime-JzBkV6Rc.js → InsightsChartAverageRuntime-Db4OWo7M.js} +4 -4
  20. package/dist/assets/{InsightsChartFailed-DMD3c7zM.js → InsightsChartFailed-DjssZ9vc.js} +4 -4
  21. package/dist/assets/{InsightsChartFailureRate-D_qeZo4f.js → InsightsChartFailureRate-C4U_fOhA.js} +4 -4
  22. package/dist/assets/{InsightsChartTimeSaved-Cw2T-Wvp.js → InsightsChartTimeSaved-DmcamM8z.js} +4 -4
  23. package/dist/assets/{InsightsChartTotal-DlF47gob.js → InsightsChartTotal-ywrK30zz.js} +4 -4
  24. package/dist/assets/{InsightsDashboard-CxQ9H296.js → InsightsDashboard-CM-ieUCq.js} +13 -10
  25. package/dist/assets/{InsightsPaywall-hRkAfeHz.js → InsightsPaywall-D-bIgmwT.js} +1 -1
  26. package/dist/assets/{InsightsSummary-BcXd-3nU.js → InsightsSummary-CwTpu3sa.js} +1 -1
  27. package/dist/assets/{InsightsTableWorkflows-ybloXdDn.js → InsightsTableWorkflows-CVtm_fGN.js} +2 -2
  28. package/dist/assets/{Logo-BGe7-2Vd.js → Logo-nyJoHWQJ.js} +1 -1
  29. package/dist/assets/{LogsPanel-mTaFEGk_.css → LogsPanel-D7j-yJQx.css} +14 -14
  30. package/dist/assets/{LogsPanel-DtTp6kY0.js → LogsPanel-mX9Nf6VB.js} +138 -36
  31. package/dist/assets/{MainHeader-h2DV-VuD.js → MainHeader-DrG-_mAG.js} +31 -21
  32. package/dist/assets/{MainSidebar-AAHHRXFA.js → MainSidebar-BMWCsLJG.js} +2 -2
  33. package/dist/assets/{NodeCreation-nHiG-Lhi.js → NodeCreation-CO1xHNgA.js} +3 -3
  34. package/dist/assets/{NodeCreator-weAzsmlU.js → NodeCreator-Bcr66G_2.js} +174 -68
  35. package/dist/assets/{NodeCreator-D18StsVZ.css → NodeCreator-Cp8Apzva.css} +38 -21
  36. package/dist/assets/{NodeDetailsView-BsXbcyfb.js → NodeDetailsView-BFW65Lly.js} +32 -18
  37. package/dist/assets/{NodeDetailsView-DpO8nTmN.css → NodeDetailsView-BtWGMS7Y.css} +16 -16
  38. package/dist/assets/{useCanvasMapping-CvcOHj5p.js → NodeView-4aDk41Oy.js} +3660 -11463
  39. package/dist/assets/{useCanvasMapping-CFf4cwnq.css → NodeView-U4YkXSfU.css} +307 -4
  40. package/dist/assets/{ProjectCardBadge-3xpk5Z4e.js → ProjectCardBadge-CLVVfcVb.js} +1 -1
  41. package/dist/assets/{ProjectHeader-CpoOisjf.js → ProjectHeader-DQk1kmw3.js} +2 -2
  42. package/dist/assets/{ProjectSettings-B__3XaPY.js → ProjectSettings-BLTHRnTQ.js} +4 -3
  43. package/dist/assets/{PushConnectionTracker.vue_vue_type_script_setup_true_lang-DaoPdG_5.js → PushConnectionTracker.vue_vue_type_script_setup_true_lang-DhLSSpy6.js} +1 -1
  44. package/dist/assets/{ResourcesListLayout-DAxou314.js → ResourcesListLayout-BlDcQdXw.js} +2 -2
  45. package/dist/assets/{RunData-fnd-jejc.js → RunData-C67Kx3bc.js} +22 -21
  46. package/dist/assets/{RunDataAi-Ck3VGKP_.js → RunDataAi-_rd0qTgN.js} +3 -3
  47. package/dist/assets/{RunDataJson-B80Z4URL.js → RunDataJson-BP0x4Zdv.js} +6 -7
  48. package/dist/assets/{RunDataJsonActions-CdZi1Qul.js → RunDataJsonActions-Bc0fqS6Y.js} +1 -1
  49. package/dist/assets/{RunDataParsedAiContent-BczxQ63H.js → RunDataParsedAiContent-l1979DuT.js} +4 -5
  50. package/dist/assets/{RunDataSearch-C4KmCz4c.js → RunDataSearch-CCGPQjFW.js} +1 -1
  51. package/dist/assets/{RunDataTable-CsLCZIWp.js → RunDataTable-uzdBjxmW.js} +2 -3
  52. package/dist/assets/{SamlOnboarding-DkhjCrPa.js → SamlOnboarding-D4xkCaRS.js} +3 -3
  53. package/dist/assets/{SettingsApiView-Ci2-rEpm.js → SettingsApiView-ijuSJs-i.js} +1 -1
  54. package/dist/assets/{SettingsCommunityNodesView-_UOppuqS.js → SettingsCommunityNodesView-D3I8P7Ea.js} +4 -4
  55. package/dist/assets/{SettingsExternalSecrets-DHIkKr53.js → SettingsExternalSecrets-ndwnYVtu.js} +1 -1
  56. package/dist/assets/{SettingsLdapView-B8ezgdqP.js → SettingsLdapView-Dzhh3gD4.js} +1 -1
  57. package/dist/assets/{SettingsLogStreamingView-YP6Xy7Fe.js → SettingsLogStreamingView-D-Rr-Jph.js} +1 -1
  58. package/dist/assets/{SettingsPersonalView-BmbFyWPb.js → SettingsPersonalView-Cf1cBUw8.js} +1 -1
  59. package/dist/assets/{SettingsSourceControl-DwaOdDke.js → SettingsSourceControl-BXRyD_N0.js} +1 -1
  60. package/dist/assets/{SettingsSso-DOC-P2wt.js → SettingsSso-DZTsjRCO.js} +1 -1
  61. package/dist/assets/{SettingsUsageAndPlan-DVOLlEkG.js → SettingsUsageAndPlan-BqY4ptNL.js} +1 -1
  62. package/dist/assets/{SettingsUsersView-CN_KLeIm.js → SettingsUsersView-eqXFp615.js} +1 -1
  63. package/dist/assets/{SettingsView-DiAhLyco.js → SettingsView-CHSTMDKz.js} +1 -1
  64. package/dist/assets/{SetupView-OE_yCNOU.js → SetupView-D6-b4i8i.js} +3 -3
  65. package/dist/assets/{SetupWorkflowCredentialsButton-Dx1IkZgW.js → SetupWorkflowCredentialsButton-6SWeqGx-.js} +1 -1
  66. package/dist/assets/{SetupWorkflowFromTemplateView-lQXKgIuL.js → SetupWorkflowFromTemplateView-DTZ8dEhY.js} +3 -3
  67. package/dist/assets/{SigninView-BWSrzbF7.js → SigninView-B3mpecGJ.js} +3 -3
  68. package/dist/assets/{SignoutView-DxGgFxt2.js → SignoutView-Bq9cEhcZ.js} +1 -1
  69. package/dist/assets/{SignupView-Dtu5bMqF.js → SignupView-BTyAq-gW.js} +3 -3
  70. package/dist/assets/{TemplateDetails-CQ7TYqsP.js → TemplateDetails-Bf7Xg-KJ.js} +1 -1
  71. package/dist/assets/{TemplateList-Cxmv-0p-.js → TemplateList-BmXxTP4v.js} +1 -1
  72. package/dist/assets/{TemplatesCollectionView-xvV6FXib.js → TemplatesCollectionView-DKwycT_4.js} +5 -5
  73. package/dist/assets/{TemplatesSearchView-CsECyZ52.js → TemplatesSearchView-ciluP1sL.js} +3 -3
  74. package/dist/assets/{TemplatesView-DrEKpZTU.js → TemplatesView-CDdQbnxe.js} +1 -1
  75. package/dist/assets/{TemplatesWorkflowView-iSAL_yol.js → TemplatesWorkflowView-uQ3eG-nR.js} +5 -5
  76. package/dist/assets/{VariablesView-Cg2WSt_e.js → VariablesView-Bve2WEng.js} +4 -4
  77. package/dist/assets/{WorkerView-BG-Dl0Ej.js → WorkerView-CUyaAqvY.js} +6 -6
  78. package/dist/assets/{WorkflowActivator-e7wvW1kJ.js → WorkflowActivator-DZSvs7Ye.js} +2 -2
  79. package/dist/assets/{WorkflowExecutionsInfoAccordion-CijtfO0l.js → WorkflowExecutionsInfoAccordion-DTbkpnyq.js} +1 -1
  80. package/dist/assets/{WorkflowExecutionsLandingPage-Do4y1yOx.js → WorkflowExecutionsLandingPage-DNc0pN7t.js} +2 -2
  81. package/dist/assets/{WorkflowExecutionsPreview-Bqo_3PXl.js → WorkflowExecutionsPreview-SdFojcu-.js} +5 -6
  82. package/dist/assets/{WorkflowExecutionsView-C1gS45nc.js → WorkflowExecutionsView-CAbXPlyv.js} +7 -8
  83. package/dist/assets/{WorkflowHistory-CypQw7rC.js → WorkflowHistory-BIFuha5h.js} +3 -3
  84. package/dist/assets/{WorkflowOnboardingView-DoKXpaNj.js → WorkflowOnboardingView-DLRgnF3H.js} +1 -1
  85. package/dist/assets/{WorkflowPreview-Bxs5XzBX.js → WorkflowPreview-DRSvh1f-.js} +1 -1
  86. package/dist/assets/{WorkflowsView-BlvgD3xI.js → WorkflowsView-DOQhvV_X.js} +9 -9
  87. package/dist/assets/{useClearExecutionButtonVisible-DFNEJves.js → canvas-CdHFQJm7.js} +3 -1
  88. package/dist/assets/{chartjs.utils-CuWcgqCr.js → chartjs.utils-hlpJdzhb.js} +2 -2
  89. package/dist/assets/{easyAiWorkflowUtils-_kvYb5hw.js → easyAiWorkflowUtils-GnIqpmRr.js} +1 -1
  90. package/dist/assets/{global-link-actions-DG0SjhQE.js → global-link-actions-CExoAUZJ.js} +1 -1
  91. package/dist/assets/{import-curl-DQ6uPzZ1.js → import-curl-D2S8-TVc.js} +1 -1
  92. package/dist/assets/{index-hdsPF3tl.js → index-BSlk84mz.js} +16505 -7040
  93. package/dist/assets/{index-BA8d2DN9.css → index-DH8MNLw5.css} +123 -70
  94. package/dist/assets/{index-vIybYvt3.js → index-lOeP0Jxq.js} +1 -1
  95. package/dist/assets/{pickBy-DmKUpB7M.js → pickBy-BoYQMT9v.js} +1 -1
  96. package/dist/assets/{templateActions-DxoxchKp.js → templateActions-CAEk7dfj.js} +1 -1
  97. package/dist/assets/{typescript.worker-B1loTpxy.js → typescript.worker-DIrCbxuR.js} +1 -1
  98. package/dist/assets/{useBeforeUnload-B7JAQiE8.js → useBeforeUnload-COWlK6zC.js} +1 -1
  99. package/dist/assets/{useExecutionDebugging-DsRIfE0y.js → useExecutionDebugging-DOtIA9Qr.js} +1 -1
  100. package/dist/assets/{useExecutionHelpers-CEOL8_vt.js → useExecutionHelpers-q1_8c2Pm.js} +1 -2
  101. package/dist/assets/{useImportCurlCommand-DdIN4YaF.js → useImportCurlCommand-CbwqixK0.js} +2 -2
  102. package/dist/assets/{useProjectPages-OGc-GAxb.js → useProjectPages-DlqnxMvy.js} +1 -1
  103. package/dist/assets/{usePushConnection-DNGIaS0A.js → usePushConnection-Bysa9RG-.js} +22 -3
  104. package/dist/assets/{useWorkflowActivate-CJ1hLmv2.js → useWorkflowActivate-B1ps647W.js} +1 -1
  105. package/dist/assets/{useWorkflowSaving-BuokdhTC.js → useWorkflowSaving-BVNVyvlZ.js} +1 -1
  106. package/dist/index.html +2 -2
  107. package/package.json +1 -1
  108. package/dist/assets/CollectionParameter-BJtiV9En.js +0 -4
  109. package/dist/assets/NodeView-BY1O3wWl.js +0 -1762
  110. package/dist/assets/NodeView-C3A-bM1O.css +0 -304
  111. package/dist/assets/TestDefinitionEditView-C3ohfu_r.js +0 -1463
  112. package/dist/assets/TestDefinitionEditView-Cwkrz308.css +0 -1189
  113. package/dist/assets/TestDefinitionListView-Dwto0jxH.js +0 -631
  114. package/dist/assets/TestDefinitionNewView-9xVUm2ZJ.js +0 -75
  115. package/dist/assets/TestDefinitionRootView-DFT60fWE.css +0 -126
  116. package/dist/assets/TestDefinitionRootView-DLurQ4xl.js +0 -39
  117. package/dist/assets/dateFormatter-LbucaaRt.js +0 -21
  118. package/dist/assets/useTestDefinitionForm-Bi6EgFVm.js +0 -154
@@ -1,1762 +0,0 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/NodeCreation-nHiG-Lhi.js","assets/index-hdsPF3tl.js","assets/index-BA8d2DN9.css","assets/NodeCreation-RKvezEeg.css","assets/NodeDetailsView-BsXbcyfb.js","assets/import-curl-DQ6uPzZ1.js","assets/RunData-fnd-jejc.js","assets/FileSaver.min-C1p9Eies.js","assets/useExecutionHelpers-CEOL8_vt.js","assets/dateFormatter-LbucaaRt.js","assets/RunData-CE5FsU6k.css","assets/RunDataAi-Ck3VGKP_.js","assets/RunDataParsedAiContent-BczxQ63H.js","assets/RunDataParsedAiContent-9EEUzCKp.css","assets/RunDataAi-D9VLFXIf.css","assets/useWorkflowActivate-CJ1hLmv2.js","assets/NodeDetailsView-DpO8nTmN.css","assets/SetupWorkflowCredentialsButton-Dx1IkZgW.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, bI as toRef, q as computed, r as ref, bR as refThrottled, i as createElementBlock, k as createBaseVNode, x as renderSlot, f as createCommentVNode, b8 as mergeProps, m as unref, n as normalizeClass, _ as _export_sfc, c as useI18n, bL as KeyboardShortcutTooltip, w as withCtx, j as createVNode, b3 as withModifiers, bS as reactive, o as onMounted, bc 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, bT as useNodeCreatorStore, p as useSettingsStore, bU as useCredentialsStore, bV as useEnvironmentsStore, bW as useExternalSecretsStore, Z as useRootStore, at as useExecutionsStore, $ as useCanvasStore, a3 as useNpsSurveyStore, bX as useHistoryStore, a1 as useProjectsStore, u as useUsersStore, E as useTagsStore, P as usePushConnectionStore, as as useNDVStore, aN as useTemplatesStore, bY as useBuilderStore, a2 as useFoldersStore, bZ as useAgentRequestStore, aY as useLogsStore, bB as useRunWorkflow, b_ as useCanvasOperations, bg as useClipboard, S as PLACEHOLDER_EMPTY_WORKFLOW_ID, b$ as NEW_WORKFLOW_ID, V as VIEWS, c0 as START_NODE_TYPE, c1 as getNodeViewTab, s as MAIN_HEADER_TABS, c2 as VALID_WORKFLOW_IMPORT_URL_REGEX, ai as useMessage, aj as MODAL_CONFIRM, c3 as jsonParse, a7 as getResourcePermissions, c4 as CHAT_TRIGGER_NODE_TYPE, c5 as MANUAL_CHAT_TRIGGER_NODE_TYPE, X as watch, c6 as onBeforeRouteLeave, az as onBeforeMount, ak as WORKFLOW_SETTINGS_MODAL_KEY, aP as useExternalHooks, c7 as onActivated, c8 as onDeactivated, y as onBeforeUnmount, c9 as Suspense, ca as defineAsyncComponent, F as Fragment, cb as N8nCallout, ao as __vitePreload, aa as EnterpriseEditionFeature, z as nextTick, ag as useTelemetry, cc as tryToParseNumber, ah as nodeViewEventBus, by as NodeConnectionTypes, cd as createCanvasConnectionHandleString, ce as isValidNodeConnectionType, cf as CanvasConnectionMode, aF as sourceControlEventBus, cg as getNodesWithNormalizedPosition, aq as h, ch as NODE_CREATOR_OPEN_SOURCES, ci as CanvasNodeRenderType, ay as STICKY_NODE_TYPE, cj as needsAgentInput, ck as FROM_AI_PARAMETERS_MODAL_KEY, cl as historyBus, cm as DRAG_EVENT_DATA_KEY } from "./index-hdsPF3tl.js";
3
- import { u as useVueFlow, a as useCanvasMapping, C as Canvas } from "./useCanvasMapping-CvcOHj5p.js";
4
- import { g as globalLinkActionsEventBus } from "./global-link-actions-DG0SjhQE.js";
5
- import { u as useExecutionDebugging } from "./useExecutionDebugging-DsRIfE0y.js";
6
- import { u as useBeforeUnload } from "./useBeforeUnload-B7JAQiE8.js";
7
- import { g as getEasyAiWorkflowJson } from "./easyAiWorkflowUtils-_kvYb5hw.js";
8
- import { u as useClearExecutionButtonVisible } from "./useClearExecutionButtonVisible-DFNEJves.js";
9
- import { u as useWorkflowSaving } from "./useWorkflowSaving-BuokdhTC.js";
10
- const _sfc_main$7 = /* @__PURE__ */ defineComponent({
11
- __name: "CanvasChatButton",
12
- props: {
13
- type: {},
14
- label: {}
15
- },
16
- setup(__props) {
17
- return (_ctx, _cache) => {
18
- const _component_N8nButton = resolveComponent("N8nButton");
19
- return openBlock(), createBlock(_component_N8nButton, {
20
- label: _ctx.label,
21
- size: "large",
22
- icon: "comment",
23
- type: _ctx.type,
24
- "data-test-id": "workflow-chat-button"
25
- }, null, 8, ["label", "type"]);
26
- };
27
- }
28
- });
29
- const _sfc_main$6 = /* @__PURE__ */ defineComponent({
30
- ...{
31
- inheritAttrs: false
32
- },
33
- __name: "WorkflowCanvas",
34
- props: {
35
- id: { default: "canvas" },
36
- workflow: {},
37
- workflowObject: {},
38
- fallbackNodes: { default: () => [] },
39
- showFallbackNodes: { type: Boolean, default: true },
40
- eventBus: { default: () => createEventBus() },
41
- readOnly: { type: Boolean },
42
- executing: { type: Boolean }
43
- },
44
- setup(__props) {
45
- const props = __props;
46
- const $style = useCssModule();
47
- const { onNodesInitialized } = useVueFlow({ id: props.id });
48
- const workflow = toRef(props, "workflow");
49
- const workflowObject = toRef(props, "workflowObject");
50
- const nodes = computed(() => {
51
- return props.showFallbackNodes ? [...props.workflow.nodes, ...props.fallbackNodes] : props.workflow.nodes;
52
- });
53
- const connections = computed(() => props.workflow.connections);
54
- const { nodes: mappedNodes, connections: mappedConnections } = useCanvasMapping({
55
- nodes,
56
- connections,
57
- workflowObject
58
- });
59
- const initialFitViewDone = ref(false);
60
- onNodesInitialized(() => {
61
- if (!initialFitViewDone.value || props.showFallbackNodes) {
62
- props.eventBus.emit("fitView");
63
- initialFitViewDone.value = true;
64
- }
65
- });
66
- const mappedNodesThrottled = refThrottled(mappedNodes, 200);
67
- const mappedConnectionsThrottled = refThrottled(mappedConnections, 200);
68
- return (_ctx, _cache) => {
69
- return openBlock(), createElementBlock("div", {
70
- class: normalizeClass(unref($style).wrapper),
71
- "data-test-id": "canvas-wrapper"
72
- }, [
73
- createBaseVNode("div", {
74
- class: normalizeClass(unref($style).canvas)
75
- }, [
76
- workflow.value ? (openBlock(), createBlock(Canvas, mergeProps({
77
- key: 0,
78
- id: _ctx.id,
79
- nodes: _ctx.executing ? unref(mappedNodesThrottled) : unref(mappedNodes),
80
- connections: _ctx.executing ? unref(mappedConnectionsThrottled) : unref(mappedConnections),
81
- "event-bus": _ctx.eventBus,
82
- "read-only": _ctx.readOnly
83
- }, _ctx.$attrs), null, 16, ["id", "nodes", "connections", "event-bus", "read-only"])) : createCommentVNode("", true)
84
- ], 2),
85
- renderSlot(_ctx.$slots, "default")
86
- ], 2);
87
- };
88
- }
89
- });
90
- const wrapper = "_wrapper_17o0o_123";
91
- const canvas = "_canvas_17o0o_131";
92
- const style0$1 = {
93
- wrapper,
94
- canvas
95
- };
96
- const cssModules$1 = {
97
- "$style": style0$1
98
- };
99
- const WorkflowCanvas = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["__cssModules", cssModules$1]]);
100
- const _sfc_main$5 = /* @__PURE__ */ defineComponent({
101
- __name: "CanvasRunWorkflowButton",
102
- props: {
103
- waitingForWebhook: { type: Boolean },
104
- executing: { type: Boolean },
105
- disabled: { type: Boolean }
106
- },
107
- emits: ["mouseenter", "mouseleave", "click"],
108
- setup(__props) {
109
- const props = __props;
110
- const i18n = useI18n();
111
- const label = computed(() => {
112
- if (!props.executing) {
113
- return i18n.baseText("nodeView.runButtonText.executeWorkflow");
114
- }
115
- if (props.waitingForWebhook) {
116
- return i18n.baseText("nodeView.runButtonText.waitingForTriggerEvent");
117
- }
118
- return i18n.baseText("nodeView.runButtonText.executingWorkflow");
119
- });
120
- return (_ctx, _cache) => {
121
- const _component_N8nButton = resolveComponent("N8nButton");
122
- return openBlock(), createBlock(KeyboardShortcutTooltip, {
123
- label: label.value,
124
- shortcut: { metaKey: true, keys: ["↵"] }
125
- }, {
126
- default: withCtx(() => [
127
- createVNode(_component_N8nButton, {
128
- loading: _ctx.executing,
129
- label: label.value,
130
- disabled: _ctx.disabled,
131
- size: "large",
132
- icon: "flask",
133
- type: "primary",
134
- "data-test-id": "execute-workflow-button",
135
- onMouseenter: _cache[0] || (_cache[0] = ($event) => _ctx.$emit("mouseenter", $event)),
136
- onMouseleave: _cache[1] || (_cache[1] = ($event) => _ctx.$emit("mouseleave", $event)),
137
- onClick: _cache[2] || (_cache[2] = withModifiers(($event) => _ctx.$emit("click", $event), ["stop"]))
138
- }, null, 8, ["loading", "label", "disabled"])
139
- ]),
140
- _: 1
141
- }, 8, ["label"]);
142
- };
143
- }
144
- });
145
- const state = reactive({
146
- customActions: {},
147
- delegatedClickHandler: null
148
- });
149
- function useGlobalLinkActions() {
150
- function registerCustomAction({ key, action }) {
151
- state.customActions[key] = action;
152
- }
153
- function unregisterCustomAction(key) {
154
- const { [key]: _, ...rest } = state.customActions;
155
- state.customActions = rest;
156
- }
157
- function getElementAttributes(element) {
158
- const attributesObject = {};
159
- for (let i = 0; i < element.attributes.length; i++) {
160
- const attr = element.attributes[i];
161
- if (attr.name.startsWith("data-action-parameter-")) {
162
- attributesObject[attr.name.replace("data-action-parameter-", "")] = attr.value;
163
- }
164
- }
165
- return attributesObject;
166
- }
167
- function delegateClick(e) {
168
- const clickedElement = e.target;
169
- if (!(clickedElement instanceof Element) || clickedElement.tagName !== "A") return;
170
- const actionAttribute = clickedElement.getAttribute("data-action");
171
- if (actionAttribute && typeof availableActions.value[actionAttribute] === "function") {
172
- e.preventDefault();
173
- const elementAttributes = getElementAttributes(clickedElement);
174
- availableActions.value[actionAttribute](elementAttributes);
175
- }
176
- }
177
- function reload() {
178
- if (window.top) {
179
- window.top.location.reload();
180
- } else {
181
- window.location.reload();
182
- }
183
- }
184
- const availableActions = computed(() => ({
185
- reload,
186
- ...state.customActions
187
- }));
188
- onMounted(() => {
189
- if (state.delegatedClickHandler) return;
190
- state.delegatedClickHandler = delegateClick;
191
- window.addEventListener("click", delegateClick);
192
- globalLinkActionsEventBus.on("registerGlobalLinkAction", registerCustomAction);
193
- });
194
- onUnmounted(() => {
195
- window.removeEventListener("click", delegateClick);
196
- state.delegatedClickHandler = null;
197
- globalLinkActionsEventBus.off("registerGlobalLinkAction", registerCustomAction);
198
- });
199
- return {
200
- registerCustomAction,
201
- unregisterCustomAction
202
- };
203
- }
204
- const _sfc_main$4 = /* @__PURE__ */ defineComponent({
205
- __name: "CanvasStopCurrentExecutionButton",
206
- props: {
207
- stopping: { type: Boolean }
208
- },
209
- setup(__props) {
210
- const props = __props;
211
- const i18n = useI18n();
212
- const title = computed(
213
- () => props.stopping ? i18n.baseText("nodeView.stoppingCurrentExecution") : i18n.baseText("nodeView.stopCurrentExecution")
214
- );
215
- return (_ctx, _cache) => {
216
- const _component_N8nIconButton = resolveComponent("N8nIconButton");
217
- return openBlock(), createBlock(_component_N8nIconButton, {
218
- icon: "stop",
219
- size: "large",
220
- class: "stop-execution",
221
- type: "secondary",
222
- title: title.value,
223
- loading: _ctx.stopping,
224
- "data-test-id": "stop-execution-button"
225
- }, null, 8, ["title", "loading"]);
226
- };
227
- }
228
- });
229
- const _sfc_main$3 = /* @__PURE__ */ defineComponent({
230
- __name: "CanvasStopWaitingForWebhookButton",
231
- setup(__props) {
232
- const i18n = useI18n();
233
- return (_ctx, _cache) => {
234
- const _component_N8nIconButton = resolveComponent("N8nIconButton");
235
- return openBlock(), createBlock(_component_N8nIconButton, {
236
- class: "stop-execution",
237
- icon: "stop",
238
- size: "large",
239
- title: unref(i18n).baseText("nodeView.stopWaitingForWebhookCall"),
240
- type: "secondary",
241
- "data-test-id": "stop-execution-waiting-for-webhook-button"
242
- }, null, 8, ["title"]);
243
- };
244
- }
245
- });
246
- const _sfc_main$2 = /* @__PURE__ */ defineComponent({
247
- __name: "CanvasClearExecutionDataButton",
248
- setup(__props) {
249
- const i18n = useI18n();
250
- return (_ctx, _cache) => {
251
- const _component_N8nIconButton = resolveComponent("N8nIconButton");
252
- return openBlock(), createBlock(_component_N8nIconButton, {
253
- title: unref(i18n).baseText("nodeView.deletesTheCurrentExecutionData"),
254
- icon: "trash",
255
- size: "large",
256
- "data-test-id": "clear-execution-data-button"
257
- }, null, 8, ["title"]);
258
- };
259
- }
260
- });
261
- const _hoisted_1 = { "data-action": "reload" };
262
- const _hoisted_2 = {
263
- href: "https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.wait/",
264
- target: "_blank"
265
- };
266
- const _sfc_main$1 = /* @__PURE__ */ defineComponent({
267
- __name: "NodeViewUnfinishedWorkflowMessage",
268
- setup(__props) {
269
- const i18 = useI18n();
270
- return (_ctx, _cache) => {
271
- return openBlock(), createElementBlock("div", null, [
272
- createBaseVNode("a", _hoisted_1, toDisplayString(unref(i18).baseText("nodeView.refresh")), 1),
273
- createTextVNode(" " + toDisplayString(unref(i18).baseText("nodeView.toSeeTheLatestStatus")) + ". ", 1),
274
- _cache[0] || (_cache[0] = createBaseVNode("br", null, null, -1)),
275
- createBaseVNode("a", _hoisted_2, toDisplayString(unref(i18).baseText("nodeView.moreInfo")), 1)
276
- ]);
277
- };
278
- }
279
- });
280
- const _sfc_main = /* @__PURE__ */ defineComponent({
281
- ...{
282
- name: "NodeView"
283
- },
284
- __name: "NodeView",
285
- setup(__props) {
286
- const LazyNodeCreation = defineAsyncComponent(
287
- async () => await __vitePreload(() => import("./NodeCreation-nHiG-Lhi.js").then((n) => n.N), true ? __vite__mapDeps([0,1,2,3]) : void 0)
288
- );
289
- const LazyNodeDetailsView = defineAsyncComponent(
290
- async () => await __vitePreload(() => import("./NodeDetailsView-BsXbcyfb.js"), true ? __vite__mapDeps([4,1,2,5,6,7,8,9,10,11,12,13,14,15,16]) : void 0)
291
- );
292
- const LazySetupWorkflowCredentialsButton = defineAsyncComponent(
293
- async () => await __vitePreload(() => import("./SetupWorkflowCredentialsButton-Dx1IkZgW.js"), true ? __vite__mapDeps([17,1,2]) : void 0)
294
- );
295
- const $style = useCssModule();
296
- const router = useRouter();
297
- const route = useRoute();
298
- const i18n = useI18n();
299
- const telemetry = useTelemetry();
300
- const externalHooks = useExternalHooks();
301
- const toast = useToast();
302
- const message = useMessage();
303
- const documentTitle = useDocumentTitle();
304
- const workflowHelpers = useWorkflowHelpers({ router });
305
- const nodeHelpers = useNodeHelpers();
306
- const nodeTypesStore = useNodeTypesStore();
307
- const uiStore = useUIStore();
308
- const workflowsStore = useWorkflowsStore();
309
- const sourceControlStore = useSourceControlStore();
310
- const nodeCreatorStore = useNodeCreatorStore();
311
- const settingsStore = useSettingsStore();
312
- const credentialsStore = useCredentialsStore();
313
- const environmentsStore = useEnvironmentsStore();
314
- const externalSecretsStore = useExternalSecretsStore();
315
- const rootStore = useRootStore();
316
- const executionsStore = useExecutionsStore();
317
- const canvasStore = useCanvasStore();
318
- const npsSurveyStore = useNpsSurveyStore();
319
- const historyStore = useHistoryStore();
320
- const projectsStore = useProjectsStore();
321
- const usersStore = useUsersStore();
322
- const tagsStore = useTagsStore();
323
- const pushConnectionStore = usePushConnectionStore();
324
- const ndvStore = useNDVStore();
325
- const templatesStore = useTemplatesStore();
326
- const builderStore = useBuilderStore();
327
- const foldersStore = useFoldersStore();
328
- const agentRequestStore = useAgentRequestStore();
329
- const logsStore = useLogsStore();
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
- startChat
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(() => logsStore.isOpen);
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(_id, event) {
690
- lastClickPosition.value = [event.x, event.y];
691
- closeNodeCreator();
692
- }
693
- function onSetNodeActivated(id, event) {
694
- if (event?.metaKey || event?.ctrlKey) {
695
- const didOpen = tryToOpenSubworkflowInNewTab(id);
696
- if (didOpen) {
697
- return;
698
- }
699
- }
700
- setNodeActive(id);
701
- }
702
- function onOpenSubWorkflow(id) {
703
- tryToOpenSubworkflowInNewTab(id);
704
- }
705
- function onSetNodeDeactivated() {
706
- clearNodeActive();
707
- }
708
- function onSetNodeSelected(id) {
709
- closeNodeCreator();
710
- setNodeSelected(id);
711
- }
712
- async function onCopyNodes(ids) {
713
- await copyNodes(ids);
714
- toast.showMessage({ title: i18n.baseText("generic.copiedToClipboard"), type: "success" });
715
- }
716
- async function onClipboardPaste(plainTextData) {
717
- if (getNodeViewTab(route) !== MAIN_HEADER_TABS.WORKFLOW || !keyBindingsEnabled.value || !checkIfEditingIsAllowed()) {
718
- return;
719
- }
720
- let workflowData = null;
721
- if (plainTextData.match(VALID_WORKFLOW_IMPORT_URL_REGEX)) {
722
- const importConfirm = await message.confirm(
723
- i18n.baseText("nodeView.confirmMessage.onClipboardPasteEvent.message", {
724
- interpolate: { plainTextData }
725
- }),
726
- i18n.baseText("nodeView.confirmMessage.onClipboardPasteEvent.headline"),
727
- {
728
- type: "warning",
729
- confirmButtonText: i18n.baseText(
730
- "nodeView.confirmMessage.onClipboardPasteEvent.confirmButtonText"
731
- ),
732
- cancelButtonText: i18n.baseText(
733
- "nodeView.confirmMessage.onClipboardPasteEvent.cancelButtonText"
734
- )
735
- }
736
- );
737
- if (importConfirm !== MODAL_CONFIRM) {
738
- return;
739
- }
740
- workflowData = await fetchWorkflowDataFromUrl(plainTextData);
741
- } else {
742
- workflowData = jsonParse(plainTextData, { fallbackValue: null });
743
- }
744
- if (!workflowData) {
745
- return;
746
- }
747
- const result = await importWorkflowData(workflowData, "paste", {
748
- importTags: false,
749
- viewport: viewportBoundaries.value
750
- });
751
- selectNodes(result.nodes?.map((node) => node.id) ?? []);
752
- }
753
- async function onCutNodes(ids) {
754
- if (isCanvasReadOnly.value) {
755
- await copyNodes(ids);
756
- } else {
757
- await cutNodes(ids);
758
- }
759
- }
760
- async function onDuplicateNodes(ids) {
761
- if (!checkIfEditingIsAllowed()) {
762
- return;
763
- }
764
- const newIds = await duplicateNodes(ids, {
765
- viewport: viewportBoundaries.value
766
- });
767
- selectNodes(newIds);
768
- }
769
- function onPinNodes(ids, source) {
770
- if (!checkIfEditingIsAllowed()) {
771
- return;
772
- }
773
- toggleNodesPinned(ids, source);
774
- }
775
- async function onSaveWorkflow() {
776
- const workflowIsSaved = !uiStore.stateIsDirty;
777
- const workflowIsArchived = workflowsStore.workflow.isArchived;
778
- if (workflowIsSaved || workflowIsArchived) {
779
- return;
780
- }
781
- const saved = await workflowHelpers.saveCurrentWorkflow();
782
- if (saved) {
783
- canvasEventBus.emit("saved:workflow");
784
- }
785
- }
786
- function addWorkflowSavedEventBindings() {
787
- canvasEventBus.on("saved:workflow", npsSurveyStore.fetchPromptsData);
788
- canvasEventBus.on("saved:workflow", onSaveFromWithinNDV);
789
- }
790
- function removeWorkflowSavedEventBindings() {
791
- canvasEventBus.off("saved:workflow", npsSurveyStore.fetchPromptsData);
792
- canvasEventBus.off("saved:workflow", onSaveFromWithinNDV);
793
- canvasEventBus.off("saved:workflow", onSaveFromWithinExecutionDebug);
794
- }
795
- async function onSaveFromWithinNDV() {
796
- if (ndvStore.activeNodeName) {
797
- toast.showMessage({
798
- title: i18n.baseText("generic.workflowSaved"),
799
- type: "success"
800
- });
801
- }
802
- }
803
- async function onCreateWorkflow() {
804
- await router.push({ name: VIEWS.NEW_WORKFLOW });
805
- }
806
- function onRenameNode(parameterData) {
807
- if (parameterData.name === "name" && parameterData.oldValue) {
808
- void renameNode(parameterData.oldValue, parameterData.value);
809
- }
810
- }
811
- async function onOpenRenameNodeModal(id) {
812
- const currentName = workflowsStore.getNodeById(id)?.name ?? "";
813
- if (!keyBindingsEnabled.value || document.querySelector(".rename-prompt")) return;
814
- try {
815
- const promptResponsePromise = message.prompt(
816
- i18n.baseText("nodeView.prompt.newName") + ":",
817
- i18n.baseText("nodeView.prompt.renameNode") + `: ${currentName}`,
818
- {
819
- customClass: "rename-prompt",
820
- confirmButtonText: i18n.baseText("nodeView.prompt.rename"),
821
- cancelButtonText: i18n.baseText("nodeView.prompt.cancel"),
822
- inputErrorMessage: i18n.baseText("nodeView.prompt.invalidName"),
823
- inputValue: currentName,
824
- inputValidator: (value) => {
825
- if (!value.trim()) {
826
- return i18n.baseText("nodeView.prompt.invalidName");
827
- }
828
- return true;
829
- }
830
- }
831
- );
832
- await nextTick();
833
- const nameInput = document.querySelector(".rename-prompt .el-input__inner");
834
- nameInput?.focus();
835
- nameInput?.select();
836
- const promptResponse = await promptResponsePromise;
837
- if (promptResponse.action === MODAL_CONFIRM) {
838
- await renameNode(currentName, promptResponse.value, { trackHistory: true });
839
- }
840
- } catch (e) {
841
- }
842
- }
843
- async function onRevertRenameNode({
844
- currentName,
845
- newName
846
- }) {
847
- await revertRenameNode(currentName, newName);
848
- }
849
- function onUpdateNodeParameters(id, parameters) {
850
- setNodeParameters(id, parameters);
851
- }
852
- function onUpdateNodeInputs(id) {
853
- revalidateNodeInputConnections(id);
854
- }
855
- function onUpdateNodeOutputs(id) {
856
- revalidateNodeOutputConnections(id);
857
- }
858
- function onClickNodeAdd(source, sourceHandle) {
859
- nodeCreatorStore.openNodeCreatorForConnectingNode({
860
- connection: {
861
- source,
862
- sourceHandle
863
- },
864
- eventSource: NODE_CREATOR_OPEN_SOURCES.PLUS_ENDPOINT
865
- });
866
- }
867
- async function loadCredentials() {
868
- let options;
869
- if (workflowId.value) {
870
- options = { workflowId: workflowId.value };
871
- } else {
872
- const queryParam = typeof route.query?.projectId === "string" ? route.query?.projectId : void 0;
873
- const projectId = queryParam ?? projectsStore.personalProject?.id;
874
- if (projectId === void 0) {
875
- throw new Error(
876
- "Could not find projectId in the query nor could I find the personal project in the project store"
877
- );
878
- }
879
- options = { projectId };
880
- }
881
- await credentialsStore.fetchAllCredentialsForWorkflow(options);
882
- }
883
- function onCreateConnection(connection) {
884
- createConnection(connection, { trackHistory: true });
885
- }
886
- function onRevertCreateConnection({ connection }) {
887
- revertCreateConnection(connection);
888
- }
889
- function onCreateConnectionCancelled(event, position, mouseEvent) {
890
- const preventDefault = (mouseEvent?.target).classList?.contains("clickable");
891
- if (preventDefault) {
892
- return;
893
- }
894
- uiStore.lastInteractedWithNodeId = event.nodeId;
895
- uiStore.lastInteractedWithNodeHandle = event.handleId;
896
- uiStore.lastCancelledConnectionPosition = [position.x, position.y];
897
- setTimeout(() => {
898
- if (!event.nodeId) return;
899
- nodeCreatorStore.openNodeCreatorForConnectingNode({
900
- connection: {
901
- source: event.nodeId,
902
- sourceHandle: event.handleId
903
- },
904
- eventSource: NODE_CREATOR_OPEN_SOURCES.NODE_CONNECTION_DROP
905
- });
906
- });
907
- }
908
- function onDeleteConnection(connection) {
909
- deleteConnection(connection, { trackHistory: true });
910
- }
911
- function onRevertDeleteConnection({ connection }) {
912
- revertDeleteConnection(connection);
913
- }
914
- async function importWorkflowExact({ workflow: workflowData }) {
915
- if (!workflowData.nodes || !workflowData.connections) {
916
- throw new Error("Invalid workflow object");
917
- }
918
- resetWorkspace();
919
- await initializeData();
920
- initializeWorkspace({
921
- ...workflowData,
922
- nodes: getNodesWithNormalizedPosition(workflowData.nodes)
923
- });
924
- fitView();
925
- }
926
- async function onImportWorkflowDataEvent(data) {
927
- const workflowData = data.data;
928
- await importWorkflowData(workflowData, "file", {
929
- viewport: viewportBoundaries.value
930
- });
931
- fitView();
932
- selectNodes(workflowData.nodes?.map((node) => node.id) ?? []);
933
- if (data.tidyUp) {
934
- setTimeout(() => {
935
- canvasEventBus.emit("tidyUp", { source: "import-workflow-data" });
936
- }, 0);
937
- }
938
- }
939
- async function onImportWorkflowUrlEvent(data) {
940
- const workflowData = await fetchWorkflowDataFromUrl(data.url);
941
- if (!workflowData) {
942
- return;
943
- }
944
- await importWorkflowData(workflowData, "url", {
945
- viewport: viewportBoundaries.value
946
- });
947
- fitView();
948
- selectNodes(workflowData.nodes?.map((node) => node.id) ?? []);
949
- }
950
- function addImportEventBindings() {
951
- nodeViewEventBus.on("importWorkflowData", onImportWorkflowDataEvent);
952
- nodeViewEventBus.on("importWorkflowUrl", onImportWorkflowUrlEvent);
953
- nodeViewEventBus.on("openChat", onOpenChat);
954
- }
955
- function removeImportEventBindings() {
956
- nodeViewEventBus.off("importWorkflowData", onImportWorkflowDataEvent);
957
- nodeViewEventBus.off("importWorkflowUrl", onImportWorkflowUrlEvent);
958
- nodeViewEventBus.off("openChat", onOpenChat);
959
- }
960
- async function onAddNodesAndConnections({ nodes, connections }, dragAndDrop = false, position) {
961
- if (!checkIfEditingIsAllowed()) {
962
- return;
963
- }
964
- const addedNodes = await addNodes(nodes, {
965
- dragAndDrop,
966
- position,
967
- viewport: viewportBoundaries.value,
968
- trackHistory: true,
969
- telemetry: true
970
- });
971
- const offsetIndex = editableWorkflow.value.nodes.length - nodes.length;
972
- const mappedConnections = connections.map(({ from, to }) => {
973
- const fromNode = editableWorkflow.value.nodes[offsetIndex + from.nodeIndex];
974
- const toNode = editableWorkflow.value.nodes[offsetIndex + to.nodeIndex];
975
- const type = from.type ?? to.type ?? NodeConnectionTypes.Main;
976
- return {
977
- source: fromNode.id,
978
- sourceHandle: createCanvasConnectionHandleString({
979
- mode: CanvasConnectionMode.Output,
980
- type: isValidNodeConnectionType(type) ? type : NodeConnectionTypes.Main,
981
- index: from.outputIndex ?? 0
982
- }),
983
- target: toNode.id,
984
- targetHandle: createCanvasConnectionHandleString({
985
- mode: CanvasConnectionMode.Input,
986
- type: isValidNodeConnectionType(type) ? type : NodeConnectionTypes.Main,
987
- index: to.inputIndex ?? 0
988
- }),
989
- data: {
990
- source: {
991
- index: from.outputIndex ?? 0,
992
- type
993
- },
994
- target: {
995
- index: to.inputIndex ?? 0,
996
- type
997
- }
998
- }
999
- };
1000
- });
1001
- await addConnections(mappedConnections);
1002
- uiStore.resetLastInteractedWith();
1003
- if (addedNodes.length > 0) {
1004
- selectNodes([addedNodes[addedNodes.length - 1].id]);
1005
- }
1006
- }
1007
- async function onRevertAddNode({ node }) {
1008
- await revertAddNode(node.name);
1009
- }
1010
- async function onSwitchActiveNode(nodeName) {
1011
- const node = workflowsStore.getNodeByName(nodeName);
1012
- if (!node) return;
1013
- setNodeActiveByName(nodeName);
1014
- selectNodes([node.id]);
1015
- }
1016
- async function onOpenSelectiveNodeCreator(node, connectionType) {
1017
- nodeCreatorStore.openSelectiveNodeCreator({ node, connectionType });
1018
- }
1019
- async function onOpenNodeCreatorForTriggerNodes(source) {
1020
- nodeCreatorStore.openNodeCreatorForTriggerNodes(source);
1021
- }
1022
- function onOpenNodeCreatorFromCanvas(source) {
1023
- onToggleNodeCreator({ createNodeActive: true, source });
1024
- }
1025
- function onToggleNodeCreator(options) {
1026
- nodeCreatorStore.setNodeCreatorState(options);
1027
- if (!options.createNodeActive && !options.hasAddedNodes) {
1028
- uiStore.resetLastInteractedWith();
1029
- }
1030
- }
1031
- function closeNodeCreator() {
1032
- if (nodeCreatorStore.isCreateNodeActive) {
1033
- nodeCreatorStore.isCreateNodeActive = false;
1034
- }
1035
- }
1036
- function onCreateSticky() {
1037
- void onAddNodesAndConnections({ nodes: [{ type: STICKY_NODE_TYPE }], connections: [] });
1038
- }
1039
- function onClickConnectionAdd(connection) {
1040
- nodeCreatorStore.openNodeCreatorForConnectingNode({
1041
- connection,
1042
- eventSource: NODE_CREATOR_OPEN_SOURCES.NODE_CONNECTION_ACTION
1043
- });
1044
- }
1045
- const workflowPermissions = computed(() => {
1046
- return workflowId.value ? getResourcePermissions(workflowsStore.getWorkflowById(workflowId.value)?.scopes).workflow : {};
1047
- });
1048
- const projectPermissions = computed(() => {
1049
- const project = route.query?.projectId ? projectsStore.myProjects.find((p) => p.id === route.query.projectId) : projectsStore.currentProject ?? projectsStore.personalProject;
1050
- return getResourcePermissions(project?.scopes);
1051
- });
1052
- const isStoppingExecution = ref(false);
1053
- const isWorkflowRunning = computed(() => workflowsStore.isWorkflowRunning);
1054
- const isExecutionWaitingForWebhook = computed(() => workflowsStore.executionWaitingForWebhook);
1055
- const isExecutionDisabled = computed(() => {
1056
- if (containsChatTriggerNodes.value && isOnlyChatTriggerNodeActive.value && !chatTriggerNodePinnedData.value) {
1057
- return true;
1058
- }
1059
- return !containsTriggerNodes.value || allTriggerNodesDisabled.value;
1060
- });
1061
- const isRunWorkflowButtonVisible = computed(
1062
- () => !isOnlyChatTriggerNodeActive.value || chatTriggerNodePinnedData.value
1063
- );
1064
- const isStopExecutionButtonVisible = computed(
1065
- () => isWorkflowRunning.value && !isExecutionWaitingForWebhook.value
1066
- );
1067
- const isStopWaitingForWebhookButtonVisible = computed(
1068
- () => isWorkflowRunning.value && isExecutionWaitingForWebhook.value
1069
- );
1070
- const isClearExecutionButtonVisible = useClearExecutionButtonVisible();
1071
- async function onRunWorkflowToNode(id) {
1072
- const node = workflowsStore.getNodeById(id);
1073
- if (!node) return;
1074
- if (needsAgentInput(node) && nodeTypesStore.isToolNode(node.type)) {
1075
- uiStore.openModalWithData({
1076
- name: FROM_AI_PARAMETERS_MODAL_KEY,
1077
- data: {
1078
- nodeName: node.name
1079
- }
1080
- });
1081
- } else {
1082
- trackRunWorkflowToNode(node);
1083
- agentRequestStore.clearAgentRequests(workflowsStore.workflowId, node.id);
1084
- void runWorkflow({ destinationNode: node.name, source: "Node.executeNode" });
1085
- }
1086
- }
1087
- function trackRunWorkflowToNode(node) {
1088
- const telemetryPayload = {
1089
- node_type: node.type,
1090
- workflow_id: workflowsStore.workflowId,
1091
- source: "canvas",
1092
- push_ref: ndvStore.pushRef
1093
- };
1094
- telemetry.track("User clicked execute node button", telemetryPayload);
1095
- void externalHooks.run("nodeView.onRunNode", telemetryPayload);
1096
- }
1097
- async function onOpenExecution(executionId) {
1098
- canvasStore.startLoading();
1099
- resetWorkspace();
1100
- await initializeData();
1101
- const data = await openExecution(executionId);
1102
- if (!data) {
1103
- return;
1104
- }
1105
- void nextTick(() => {
1106
- updateNodesIssues();
1107
- });
1108
- canvasStore.stopLoading();
1109
- fitView();
1110
- canvasEventBus.emit("open:execution", data);
1111
- void externalHooks.run("execution.open", {
1112
- workflowId: data.workflowData.id,
1113
- workflowName: data.workflowData.name,
1114
- executionId
1115
- });
1116
- telemetry.track("User opened read-only execution", {
1117
- workflow_id: data.workflowData.id,
1118
- execution_mode: data.mode,
1119
- execution_finished: data.finished
1120
- });
1121
- }
1122
- function onExecutionOpenedWithError(data) {
1123
- if (!data.finished && data.data?.resultData?.error) {
1124
- let nodeErrorFound = false;
1125
- if (data.data.resultData.runData) {
1126
- const runData = data.data.resultData.runData;
1127
- errorCheck: for (const nodeName of Object.keys(runData)) {
1128
- for (const taskData of runData[nodeName]) {
1129
- if (taskData.error) {
1130
- nodeErrorFound = true;
1131
- break errorCheck;
1132
- }
1133
- }
1134
- }
1135
- }
1136
- if (!nodeErrorFound && (data.data.resultData.error.stack ?? data.data.resultData.error.message)) {
1137
- console.error(`Execution ${data.id} error:`);
1138
- console.error(data.data.resultData.error.stack);
1139
- toast.showMessage({
1140
- title: i18n.baseText("nodeView.showError.workflowError"),
1141
- message: data.data.resultData.error.message,
1142
- type: "error",
1143
- duration: 0
1144
- });
1145
- }
1146
- }
1147
- }
1148
- function onExecutionOpenedWithWaitTill(data) {
1149
- if (data.waitTill) {
1150
- toast.showMessage({
1151
- title: i18n.baseText("nodeView.thisExecutionHasntFinishedYet"),
1152
- message: h(_sfc_main$1),
1153
- type: "warning",
1154
- duration: 0
1155
- });
1156
- }
1157
- }
1158
- function addExecutionOpenedEventBindings() {
1159
- canvasEventBus.on("open:execution", onExecutionOpenedWithError);
1160
- canvasEventBus.on("open:execution", onExecutionOpenedWithWaitTill);
1161
- }
1162
- function removeExecutionOpenedEventBindings() {
1163
- canvasEventBus.off("open:execution", onExecutionOpenedWithError);
1164
- canvasEventBus.off("open:execution", onExecutionOpenedWithWaitTill);
1165
- }
1166
- async function onStopExecution() {
1167
- isStoppingExecution.value = true;
1168
- await stopCurrentExecution();
1169
- isStoppingExecution.value = false;
1170
- }
1171
- async function onStopWaitingForWebhook() {
1172
- await stopWaitingForWebhook();
1173
- }
1174
- async function onClearExecutionData() {
1175
- workflowsStore.workflowExecutionData = null;
1176
- nodeHelpers.updateNodesExecutionIssues();
1177
- }
1178
- function onRunWorkflowButtonMouseEnter() {
1179
- nodeViewEventBus.emit("runWorkflowButton:mouseenter");
1180
- }
1181
- function onRunWorkflowButtonMouseLeave() {
1182
- nodeViewEventBus.emit("runWorkflowButton:mouseleave");
1183
- }
1184
- const chatTriggerNode = computed(() => {
1185
- return editableWorkflow.value.nodes.find((node) => node.type === CHAT_TRIGGER_NODE_TYPE);
1186
- });
1187
- const containsChatTriggerNodes = computed(() => {
1188
- return !isExecutionWaitingForWebhook.value && !!editableWorkflow.value.nodes.find(
1189
- (node) => [MANUAL_CHAT_TRIGGER_NODE_TYPE, CHAT_TRIGGER_NODE_TYPE].includes(node.type) && node.disabled !== true
1190
- );
1191
- });
1192
- const isOnlyChatTriggerNodeActive = computed(() => {
1193
- return triggerNodes.value.every((node) => node.disabled || node.type === CHAT_TRIGGER_NODE_TYPE);
1194
- });
1195
- const chatTriggerNodePinnedData = computed(() => {
1196
- if (!chatTriggerNode.value) return null;
1197
- return workflowsStore.pinDataByNodeName(chatTriggerNode.value.name);
1198
- });
1199
- function onOpenChat() {
1200
- startChat("main");
1201
- }
1202
- function addUndoRedoEventBindings() {
1203
- historyBus.on("nodeMove", onRevertNodePosition);
1204
- historyBus.on("revertAddNode", onRevertAddNode);
1205
- historyBus.on("revertRemoveNode", onRevertDeleteNode);
1206
- historyBus.on("revertAddConnection", onRevertCreateConnection);
1207
- historyBus.on("revertRemoveConnection", onRevertDeleteConnection);
1208
- historyBus.on("revertRenameNode", onRevertRenameNode);
1209
- historyBus.on("enableNodeToggle", onRevertToggleNodeDisabled);
1210
- }
1211
- function removeUndoRedoEventBindings() {
1212
- historyBus.off("nodeMove", onRevertNodePosition);
1213
- historyBus.off("revertAddNode", onRevertAddNode);
1214
- historyBus.off("revertRemoveNode", onRevertDeleteNode);
1215
- historyBus.off("revertAddConnection", onRevertCreateConnection);
1216
- historyBus.off("revertRemoveConnection", onRevertDeleteConnection);
1217
- historyBus.off("revertRenameNode", onRevertRenameNode);
1218
- historyBus.off("enableNodeToggle", onRevertToggleNodeDisabled);
1219
- }
1220
- async function onSourceControlPull() {
1221
- try {
1222
- await Promise.all([
1223
- environmentsStore.fetchAllVariables(),
1224
- tagsStore.fetchAll(),
1225
- loadCredentials()
1226
- ]);
1227
- if (workflowId.value && !uiStore.stateIsDirty) {
1228
- const workflowData = await workflowsStore.fetchWorkflow(workflowId.value);
1229
- if (workflowData) {
1230
- workflowHelpers.setDocumentTitle(workflowData.name, "IDLE");
1231
- openWorkflow(workflowData);
1232
- }
1233
- }
1234
- } catch (error) {
1235
- console.error(error);
1236
- }
1237
- }
1238
- function addSourceControlEventBindings() {
1239
- sourceControlEventBus.on("pull", onSourceControlPull);
1240
- }
1241
- function removeSourceControlEventBindings() {
1242
- sourceControlEventBus.off("pull", onSourceControlPull);
1243
- }
1244
- function addPostMessageEventBindings() {
1245
- window.addEventListener("message", onPostMessageReceived);
1246
- }
1247
- function removePostMessageEventBindings() {
1248
- window.removeEventListener("message", onPostMessageReceived);
1249
- }
1250
- function emitPostMessageReady() {
1251
- if (window.parent) {
1252
- window.parent.postMessage(
1253
- JSON.stringify({ command: "n8nReady", version: rootStore.versionCli }),
1254
- "*"
1255
- );
1256
- }
1257
- }
1258
- async function onPostMessageReceived(messageEvent) {
1259
- if (!messageEvent || typeof messageEvent.data !== "string" || !messageEvent.data?.includes?.('"command"')) {
1260
- return;
1261
- }
1262
- try {
1263
- const json = JSON.parse(messageEvent.data);
1264
- if (json && json.command === "openWorkflow") {
1265
- try {
1266
- await importWorkflowExact(json);
1267
- canOpenNDV.value = json.canOpenNDV ?? true;
1268
- hideNodeIssues.value = json.hideNodeIssues ?? false;
1269
- isExecutionPreview.value = false;
1270
- } catch (e) {
1271
- if (window.top) {
1272
- window.top.postMessage(
1273
- JSON.stringify({
1274
- command: "error",
1275
- message: i18n.baseText("openWorkflow.workflowImportError")
1276
- }),
1277
- "*"
1278
- );
1279
- }
1280
- toast.showError(e, i18n.baseText("openWorkflow.workflowImportError"));
1281
- }
1282
- } else if (json && json.command === "openExecution") {
1283
- try {
1284
- isProductionExecutionPreview.value = json.executionMode !== "manual" && json.executionMode !== "evaluation";
1285
- await onOpenExecution(json.executionId);
1286
- canOpenNDV.value = json.canOpenNDV ?? true;
1287
- hideNodeIssues.value = json.hideNodeIssues ?? false;
1288
- isExecutionPreview.value = true;
1289
- } catch (e) {
1290
- if (window.top) {
1291
- window.top.postMessage(
1292
- JSON.stringify({
1293
- command: "error",
1294
- message: i18n.baseText("nodeView.showError.openExecution.title")
1295
- }),
1296
- "*"
1297
- );
1298
- }
1299
- toast.showMessage({
1300
- title: i18n.baseText("nodeView.showError.openExecution.title"),
1301
- message: e.message,
1302
- type: "error"
1303
- });
1304
- }
1305
- } else if (json?.command === "setActiveExecution") {
1306
- executionsStore.activeExecution = await executionsStore.fetchExecution(
1307
- json.executionId
1308
- );
1309
- }
1310
- } catch (e) {
1311
- }
1312
- }
1313
- function checkIfEditingIsAllowed() {
1314
- if (!initializedWorkflowId.value) {
1315
- return true;
1316
- }
1317
- if (readOnlyNotification.value?.visible) {
1318
- return false;
1319
- }
1320
- if (isReadOnlyRoute.value || isReadOnlyEnvironment.value) {
1321
- const messageContext = isReadOnlyRoute.value ? "executions" : "workflows";
1322
- readOnlyNotification.value = toast.showMessage({
1323
- title: i18n.baseText(
1324
- isReadOnlyEnvironment.value ? `readOnlyEnv.showMessage.${messageContext}.title` : "readOnly.showMessage.executions.title"
1325
- ),
1326
- message: i18n.baseText(
1327
- isReadOnlyEnvironment.value ? `readOnlyEnv.showMessage.${messageContext}.message` : "readOnly.showMessage.executions.message"
1328
- ),
1329
- type: "info"
1330
- });
1331
- return false;
1332
- }
1333
- return true;
1334
- }
1335
- function checkIfRouteIsAllowed() {
1336
- if (isReadOnlyEnvironment.value && [VIEWS.NEW_WORKFLOW, VIEWS.TEMPLATE_IMPORT].find((view) => view === route.name)) {
1337
- void nextTick(async () => {
1338
- resetWorkspace();
1339
- uiStore.stateIsDirty = false;
1340
- await router.replace({ name: VIEWS.HOMEPAGE });
1341
- });
1342
- }
1343
- }
1344
- async function initializeDebugMode() {
1345
- workflowHelpers.setDocumentTitle(workflowsStore.workflowName, "DEBUG");
1346
- if (!workflowsStore.isInDebugMode) {
1347
- await applyExecutionData(route.params.executionId);
1348
- workflowsStore.isInDebugMode = true;
1349
- }
1350
- canvasEventBus.on("saved:workflow", onSaveFromWithinExecutionDebug);
1351
- }
1352
- async function onSaveFromWithinExecutionDebug() {
1353
- if (route.name !== VIEWS.EXECUTION_DEBUG) return;
1354
- await router.replace({
1355
- name: VIEWS.WORKFLOW,
1356
- params: { name: workflowId.value }
1357
- });
1358
- }
1359
- const viewportTransform = ref({ x: 0, y: 0, zoom: 1 });
1360
- const viewportDimensions = ref({ width: 0, height: 0 });
1361
- const viewportBoundaries = computed(() => {
1362
- const { x, y, zoom } = viewportTransform.value;
1363
- const { width, height } = viewportDimensions.value;
1364
- const xMin = -x / zoom;
1365
- const yMin = -y / zoom;
1366
- const xMax = (width - x) / zoom;
1367
- const yMax = (height - y) / zoom;
1368
- return { xMin, yMin, xMax, yMax };
1369
- });
1370
- function onViewportChange(viewport, dimensions) {
1371
- viewportTransform.value = viewport;
1372
- viewportDimensions.value = dimensions;
1373
- uiStore.nodeViewOffsetPosition = [viewport.x, viewport.y];
1374
- }
1375
- function fitView() {
1376
- setTimeout(() => canvasEventBus.emit("fitView"));
1377
- }
1378
- function selectNodes(ids) {
1379
- setTimeout(() => canvasEventBus.emit("nodes:select", { ids }));
1380
- }
1381
- function onClickPane(position) {
1382
- lastClickPosition.value = [position.x, position.y];
1383
- onSetNodeSelected();
1384
- }
1385
- function onSelectionEnd(position) {
1386
- lastClickPosition.value = [position.x, position.y];
1387
- }
1388
- async function onDragAndDrop(position, event) {
1389
- if (!event.dataTransfer) {
1390
- return;
1391
- }
1392
- const dropData = jsonParse(
1393
- event.dataTransfer.getData(DRAG_EVENT_DATA_KEY)
1394
- );
1395
- if (dropData) {
1396
- const insertNodePosition = [position.x, position.y];
1397
- await onAddNodesAndConnections(dropData, true, insertNodePosition);
1398
- onToggleNodeCreator({ createNodeActive: false, hasAddedNodes: true });
1399
- }
1400
- }
1401
- function registerCustomActions() {
1402
- registerCustomAction({
1403
- key: "openNodeDetail",
1404
- action: ({ node }) => {
1405
- setNodeActiveByName(node);
1406
- }
1407
- });
1408
- registerCustomAction({
1409
- key: "openSelectiveNodeCreator",
1410
- action: ({
1411
- creatorview: creatorView,
1412
- connectiontype: connectionType,
1413
- node
1414
- }) => {
1415
- nodeCreatorStore.openSelectiveNodeCreator({ node, connectionType, creatorView });
1416
- }
1417
- });
1418
- registerCustomAction({
1419
- key: "showNodeCreator",
1420
- action: () => {
1421
- ndvStore.activeNodeName = null;
1422
- void nextTick(() => {
1423
- void onOpenNodeCreatorForTriggerNodes(NODE_CREATOR_OPEN_SOURCES.TAB);
1424
- });
1425
- }
1426
- });
1427
- }
1428
- function unregisterCustomActions() {
1429
- unregisterCustomAction("openNodeDetail");
1430
- unregisterCustomAction("openSelectiveNodeCreator");
1431
- unregisterCustomAction("showNodeCreator");
1432
- }
1433
- function showAddFirstStepIfEnabled() {
1434
- if (uiStore.addFirstStepOnLoad) {
1435
- void onOpenNodeCreatorForTriggerNodes(NODE_CREATOR_OPEN_SOURCES.TRIGGER_PLACEHOLDER_BUTTON);
1436
- uiStore.addFirstStepOnLoad = false;
1437
- }
1438
- }
1439
- function updateNodeRoute(nodeId) {
1440
- const nodeUi = workflowsStore.findNodeByPartialId(nodeId);
1441
- if (nodeUi) {
1442
- setNodeActive(nodeUi.id);
1443
- } else {
1444
- toast.showToast({
1445
- title: i18n.baseText("nodeView.showMessage.ndvUrl.missingNodes.title"),
1446
- message: i18n.baseText("nodeView.showMessage.ndvUrl.missingNodes.content"),
1447
- type: "warning"
1448
- });
1449
- void router.replace({
1450
- name: route.name,
1451
- params: { name: workflowId.value }
1452
- });
1453
- }
1454
- }
1455
- watch(
1456
- () => route.name,
1457
- async (newRouteName, oldRouteName) => {
1458
- const force = newRouteName === VIEWS.NEW_WORKFLOW && oldRouteName === VIEWS.WORKFLOW || newRouteName === VIEWS.WORKFLOW && oldRouteName === VIEWS.NEW_WORKFLOW;
1459
- await initializeRoute(force);
1460
- }
1461
- );
1462
- watch(
1463
- () => {
1464
- return isLoading.value || isCanvasReadOnly.value || editableWorkflow.value.nodes.length !== 0;
1465
- },
1466
- (isReadOnlyOrLoading) => {
1467
- const defaultFallbackNodes = [
1468
- {
1469
- id: CanvasNodeRenderType.AddNodes,
1470
- name: CanvasNodeRenderType.AddNodes,
1471
- type: CanvasNodeRenderType.AddNodes,
1472
- typeVersion: 1,
1473
- position: [0, 0],
1474
- parameters: {}
1475
- }
1476
- ];
1477
- if (builderStore.isAIBuilderEnabled && builderStore.isAssistantEnabled) {
1478
- defaultFallbackNodes.unshift({
1479
- id: CanvasNodeRenderType.AIPrompt,
1480
- name: CanvasNodeRenderType.AIPrompt,
1481
- type: CanvasNodeRenderType.AIPrompt,
1482
- typeVersion: 1,
1483
- position: [-690, -15],
1484
- parameters: {}
1485
- });
1486
- }
1487
- fallbackNodes.value = isReadOnlyOrLoading ? [] : defaultFallbackNodes;
1488
- }
1489
- );
1490
- watch(
1491
- () => route.params.nodeId,
1492
- async (newId) => {
1493
- if (typeof newId !== "string" || newId === "") ndvStore.activeNodeName = null;
1494
- else {
1495
- updateNodeRoute(newId);
1496
- }
1497
- }
1498
- );
1499
- watch(
1500
- () => ndvStore.activeNode,
1501
- async (val) => {
1502
- if (![VIEWS.WORKFLOW].includes(String(route.name))) return;
1503
- const nodeId = val?.id ? workflowsStore.getPartialIdForNode(val?.id) : "";
1504
- if (nodeId !== route.params.nodeId) {
1505
- await router.replace({
1506
- name: route.name,
1507
- params: { name: workflowId.value, nodeId }
1508
- });
1509
- }
1510
- }
1511
- );
1512
- onBeforeRouteLeave(async (to, from, next) => {
1513
- const toNodeViewTab = getNodeViewTab(to);
1514
- if (toNodeViewTab === MAIN_HEADER_TABS.EXECUTIONS || from.name === VIEWS.TEMPLATE_IMPORT || toNodeViewTab === MAIN_HEADER_TABS.WORKFLOW && from.name === VIEWS.EXECUTION_DEBUG || isReadOnlyEnvironment.value) {
1515
- next();
1516
- return;
1517
- }
1518
- await useWorkflowSaving({ router }).promptSaveUnsavedWorkflowChanges(next, {
1519
- async confirm() {
1520
- if (from.name === VIEWS.NEW_WORKFLOW) {
1521
- const savedWorkflowId = workflowsStore.workflowId;
1522
- await router.replace({
1523
- name: VIEWS.WORKFLOW,
1524
- params: { name: savedWorkflowId }
1525
- });
1526
- await router.push(to);
1527
- return false;
1528
- }
1529
- workflowsStore.setWorkflowId(PLACEHOLDER_EMPTY_WORKFLOW_ID);
1530
- return true;
1531
- }
1532
- });
1533
- });
1534
- onBeforeMount(() => {
1535
- if (!isDemoRoute.value) {
1536
- pushConnectionStore.pushConnect();
1537
- }
1538
- addPostMessageEventBindings();
1539
- });
1540
- onMounted(() => {
1541
- canvasStore.startLoading();
1542
- documentTitle.reset();
1543
- resetWorkspace();
1544
- void initializeData().then(() => {
1545
- void initializeRoute().then(() => {
1546
- toast.showNotificationForViews([VIEWS.WORKFLOW, VIEWS.NEW_WORKFLOW]);
1547
- if (route.query.settings) {
1548
- uiStore.openModal(WORKFLOW_SETTINGS_MODAL_KEY);
1549
- void router.replace({ query: { settings: void 0 } });
1550
- }
1551
- }).finally(() => {
1552
- isLoading.value = false;
1553
- canvasStore.stopLoading();
1554
- void externalHooks.run("nodeView.mount").catch(() => {
1555
- });
1556
- setTimeout(() => {
1557
- if (routeNodeId.value) {
1558
- updateNodeRoute(routeNodeId.value);
1559
- }
1560
- }, 500);
1561
- emitPostMessageReady();
1562
- });
1563
- void usersStore.showPersonalizationSurvey();
1564
- checkIfRouteIsAllowed();
1565
- });
1566
- addSourceControlEventBindings();
1567
- addWorkflowSavedEventBindings();
1568
- addBeforeUnloadEventBindings();
1569
- addImportEventBindings();
1570
- addExecutionOpenedEventBindings();
1571
- registerCustomActions();
1572
- });
1573
- onActivated(async () => {
1574
- addUndoRedoEventBindings();
1575
- showAddFirstStepIfEnabled();
1576
- });
1577
- onDeactivated(() => {
1578
- uiStore.closeModal(WORKFLOW_SETTINGS_MODAL_KEY);
1579
- removeUndoRedoEventBindings();
1580
- });
1581
- onBeforeUnmount(() => {
1582
- removeSourceControlEventBindings();
1583
- removePostMessageEventBindings();
1584
- removeWorkflowSavedEventBindings();
1585
- removeBeforeUnloadEventBindings();
1586
- removeImportEventBindings();
1587
- removeExecutionOpenedEventBindings();
1588
- unregisterCustomActions();
1589
- if (!isDemoRoute.value) {
1590
- pushConnectionStore.pushDisconnect();
1591
- }
1592
- });
1593
- return (_ctx, _cache) => {
1594
- const _component_CanvasChatButton = _sfc_main$7;
1595
- return unref(editableWorkflow) && unref(editableWorkflowObject) && !isLoading.value ? (openBlock(), createBlock(WorkflowCanvas, {
1596
- key: 0,
1597
- id: unref(editableWorkflow).id,
1598
- workflow: unref(editableWorkflow),
1599
- "workflow-object": unref(editableWorkflowObject),
1600
- "fallback-nodes": fallbackNodes.value,
1601
- "show-fallback-nodes": showFallbackNodes.value,
1602
- "event-bus": unref(canvasEventBus),
1603
- "read-only": isCanvasReadOnly.value,
1604
- executing: isWorkflowRunning.value,
1605
- "key-bindings": keyBindingsEnabled.value,
1606
- "onUpdate:nodes:position": onUpdateNodesPosition,
1607
- "onUpdate:node:position": onUpdateNodePosition,
1608
- "onUpdate:node:activated": onSetNodeActivated,
1609
- "onUpdate:node:deactivated": onSetNodeDeactivated,
1610
- "onUpdate:node:selected": onSetNodeSelected,
1611
- "onUpdate:node:enabled": onToggleNodeDisabled,
1612
- "onUpdate:node:name": onOpenRenameNodeModal,
1613
- "onUpdate:node:parameters": onUpdateNodeParameters,
1614
- "onUpdate:node:inputs": onUpdateNodeInputs,
1615
- "onUpdate:node:outputs": onUpdateNodeOutputs,
1616
- "onUpdate:logsOpen": _cache[2] || (_cache[2] = ($event) => unref(logsStore).toggleOpen($event)),
1617
- "onUpdate:logs:inputOpen": unref(logsStore).toggleInputOpen,
1618
- "onUpdate:logs:outputOpen": unref(logsStore).toggleOutputOpen,
1619
- "onOpen:subWorkflow": onOpenSubWorkflow,
1620
- "onClick:node": onClickNode,
1621
- "onClick:node:add": onClickNodeAdd,
1622
- "onRun:node": onRunWorkflowToNode,
1623
- "onDelete:node": onDeleteNode,
1624
- "onCreate:connection": onCreateConnection,
1625
- "onCreate:connection:cancelled": onCreateConnectionCancelled,
1626
- "onDelete:connection": onDeleteConnection,
1627
- "onClick:connection:add": onClickConnectionAdd,
1628
- "onClick:pane": onClickPane,
1629
- "onCreate:node": onOpenNodeCreatorFromCanvas,
1630
- "onCreate:sticky": onCreateSticky,
1631
- "onDelete:nodes": onDeleteNodes,
1632
- "onUpdate:nodes:enabled": onToggleNodesDisabled,
1633
- "onUpdate:nodes:pin": onPinNodes,
1634
- "onDuplicate:nodes": onDuplicateNodes,
1635
- "onCopy:nodes": onCopyNodes,
1636
- "onCut:nodes": onCutNodes,
1637
- "onRun:workflow": _cache[3] || (_cache[3] = ($event) => unref(runEntireWorkflow)("main")),
1638
- "onSave:workflow": onSaveWorkflow,
1639
- "onCreate:workflow": onCreateWorkflow,
1640
- "onViewport:change": onViewportChange,
1641
- "onSelection:end": onSelectionEnd,
1642
- onDragAndDrop,
1643
- onTidyUp,
1644
- onStartChat: _cache[4] || (_cache[4] = ($event) => unref(startChat)())
1645
- }, {
1646
- default: withCtx(() => [
1647
- (openBlock(), createBlock(Suspense, null, {
1648
- default: withCtx(() => [
1649
- createVNode(unref(LazySetupWorkflowCredentialsButton), {
1650
- class: normalizeClass(unref($style).setupCredentialsButtonWrapper)
1651
- }, null, 8, ["class"])
1652
- ]),
1653
- _: 1
1654
- })),
1655
- !isCanvasReadOnly.value ? (openBlock(), createElementBlock("div", {
1656
- key: 0,
1657
- class: normalizeClass(unref($style).executionButtons)
1658
- }, [
1659
- isRunWorkflowButtonVisible.value ? (openBlock(), createBlock(_sfc_main$5, {
1660
- key: 0,
1661
- "waiting-for-webhook": isExecutionWaitingForWebhook.value,
1662
- disabled: isExecutionDisabled.value,
1663
- executing: isWorkflowRunning.value,
1664
- onMouseenter: onRunWorkflowButtonMouseEnter,
1665
- onMouseleave: onRunWorkflowButtonMouseLeave,
1666
- onClick: _cache[0] || (_cache[0] = ($event) => unref(runEntireWorkflow)("main"))
1667
- }, null, 8, ["waiting-for-webhook", "disabled", "executing"])) : createCommentVNode("", true),
1668
- containsChatTriggerNodes.value ? (openBlock(), createElementBlock(Fragment, { key: 1 }, [
1669
- isLogsPanelOpen.value ? (openBlock(), createBlock(_component_CanvasChatButton, {
1670
- key: 0,
1671
- type: "tertiary",
1672
- label: unref(i18n).baseText("chat.hide"),
1673
- onClick: _cache[1] || (_cache[1] = ($event) => unref(logsStore).toggleOpen(false))
1674
- }, null, 8, ["label"])) : (openBlock(), createBlock(KeyboardShortcutTooltip, {
1675
- key: 1,
1676
- label: unref(i18n).baseText("chat.open"),
1677
- shortcut: { keys: ["c"] }
1678
- }, {
1679
- default: withCtx(() => [
1680
- createVNode(_component_CanvasChatButton, {
1681
- type: "primary",
1682
- label: unref(i18n).baseText("chat.open"),
1683
- onClick: onOpenChat
1684
- }, null, 8, ["label"])
1685
- ]),
1686
- _: 1
1687
- }, 8, ["label"]))
1688
- ], 64)) : createCommentVNode("", true),
1689
- isStopExecutionButtonVisible.value ? (openBlock(), createBlock(_sfc_main$4, {
1690
- key: 2,
1691
- stopping: isStoppingExecution.value,
1692
- onClick: onStopExecution
1693
- }, null, 8, ["stopping"])) : createCommentVNode("", true),
1694
- isStopWaitingForWebhookButtonVisible.value ? (openBlock(), createBlock(_sfc_main$3, {
1695
- key: 3,
1696
- onClick: onStopWaitingForWebhook
1697
- })) : createCommentVNode("", true),
1698
- unref(isClearExecutionButtonVisible) && !unref(settingsStore).isNewLogsEnabled ? (openBlock(), createBlock(_sfc_main$2, {
1699
- key: 4,
1700
- onClick: onClearExecutionData
1701
- })) : createCommentVNode("", true)
1702
- ], 2)) : createCommentVNode("", true),
1703
- isReadOnlyEnvironment.value ? (openBlock(), createBlock(unref(N8nCallout), {
1704
- key: 1,
1705
- theme: "warning",
1706
- icon: "lock",
1707
- class: normalizeClass(unref($style).readOnlyEnvironmentNotification)
1708
- }, {
1709
- default: withCtx(() => [
1710
- createTextVNode(toDisplayString(unref(i18n).baseText("readOnlyEnv.cantEditOrRun")), 1)
1711
- ]),
1712
- _: 1
1713
- }, 8, ["class"])) : createCommentVNode("", true),
1714
- (openBlock(), createBlock(Suspense, null, {
1715
- default: withCtx(() => [
1716
- !isCanvasReadOnly.value ? (openBlock(), createBlock(unref(LazyNodeCreation), {
1717
- key: 0,
1718
- "create-node-active": unref(nodeCreatorStore).isCreateNodeActive,
1719
- "node-view-scale": viewportTransform.value.zoom,
1720
- onToggleNodeCreator,
1721
- onAddNodes: onAddNodesAndConnections
1722
- }, null, 8, ["create-node-active", "node-view-scale"])) : createCommentVNode("", true)
1723
- ]),
1724
- _: 1
1725
- })),
1726
- (openBlock(), createBlock(Suspense, null, {
1727
- default: withCtx(() => [
1728
- createVNode(unref(LazyNodeDetailsView), {
1729
- "workflow-object": unref(editableWorkflowObject),
1730
- "read-only": isCanvasReadOnly.value,
1731
- "is-production-execution-preview": isProductionExecutionPreview.value,
1732
- renaming: false,
1733
- onValueChanged: onRenameNode,
1734
- onStopExecution,
1735
- onSwitchSelectedNode: onSwitchActiveNode,
1736
- onOpenConnectionNodeCreator: onOpenSelectiveNodeCreator,
1737
- onSaveKeyboardShortcut: onSaveWorkflow
1738
- }, null, 8, ["workflow-object", "read-only", "is-production-execution-preview"])
1739
- ]),
1740
- _: 1
1741
- }))
1742
- ]),
1743
- _: 1
1744
- }, 8, ["id", "workflow", "workflow-object", "fallback-nodes", "show-fallback-nodes", "event-bus", "read-only", "executing", "key-bindings", "onUpdate:logs:inputOpen", "onUpdate:logs:outputOpen"])) : createCommentVNode("", true);
1745
- };
1746
- }
1747
- });
1748
- const executionButtons = "_executionButtons_8gz1l_123";
1749
- const setupCredentialsButtonWrapper = "_setupCredentialsButtonWrapper_8gz1l_161";
1750
- const readOnlyEnvironmentNotification = "_readOnlyEnvironmentNotification_8gz1l_167";
1751
- const style0 = {
1752
- executionButtons,
1753
- setupCredentialsButtonWrapper,
1754
- readOnlyEnvironmentNotification
1755
- };
1756
- const cssModules = {
1757
- "$style": style0
1758
- };
1759
- const NodeView = /* @__PURE__ */ _export_sfc(_sfc_main, [["__cssModules", cssModules]]);
1760
- export {
1761
- NodeView as default
1762
- };