n8n-editor-ui 1.104.1 → 1.105.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.
- package/dist/assets/{AnimatedSpinner-D6j3zAN7.js → AnimatedSpinner-CiVjnVTs.js} +1 -1
- package/dist/assets/{AnnotationTagsDropdown.ee.vue_vue_type_script_setup_true_lang-CeptN1qB.js → AnnotationTagsDropdown.ee.vue_vue_type_script_setup_true_lang-Duv062St.js} +1 -1
- package/dist/assets/{AuthView-DdzGr3if.js → AuthView-Dpa-SRT8.js} +2 -2
- package/dist/assets/{ChangePasswordView-CLbLuldY.js → ChangePasswordView-CB9uaGfm.js} +3 -3
- package/dist/assets/CollectionParameter-oBzQ1Hh-.js +4 -0
- package/dist/assets/{ConsumedTokensDetails.vue_vue_type_script_setup_true_lang-DwQ0BmLY.js → ConsumedTokensDetails.vue_vue_type_script_setup_true_lang-DIcGPKiM.js} +1 -1
- package/dist/assets/{CredentialsView-Cbm8N2D-.js → CredentialsView-AW9gSm0C.js} +8 -8
- package/dist/assets/{DemoFooter-DlHqx3Wb.js → DemoFooter-DybJBgCY.js} +6 -9
- package/dist/assets/{EmptySharedSectionActionBox.vue_vue_type_script_setup_true_lang-Dymz7mm-.js → EmptySharedSectionActionBox.vue_vue_type_script_setup_true_lang-GcMQ_YdZ.js} +1 -1
- package/dist/assets/{EntityNotFound-CmBDOsai.js → EntityNotFound-Bi2pl54e.js} +1 -1
- package/dist/assets/{EntityUnAuthorised-CNPmvmZu.js → EntityUnAuthorised-HDf2HNt2.js} +1 -1
- package/dist/assets/{ErrorView-BqgIhqko.js → ErrorView-BPodDJdx.js} +1 -1
- package/dist/assets/{EvaluationsRootView-B6RDbMu9.js → EvaluationsRootView-pO4cP-Fb.js} +1 -1
- package/dist/assets/{EvaluationsView-nr07_JFX.js → EvaluationsView-CI108a8E.js} +3 -3
- package/dist/assets/{ExecutionsTime-Bo7IOE5K.css → ExecutionsTime-etWexlXm.css} +6 -6
- package/dist/assets/{ExecutionsTime.vue_vue_type_script_setup_true_lang-Ci1SWv1r.js → ExecutionsTime.vue_vue_type_script_setup_true_lang-CGxPzqoO.js} +23 -30
- package/dist/assets/{ExecutionsView-L8QB4qb-.js → ExecutionsView-BaQKVP7R.js} +8 -9
- package/dist/assets/{FixedCollectionParameter-BMsoLNRT.js → FixedCollectionParameter-BpCwKUsj.js} +1 -1
- package/dist/assets/{ForgotMyPasswordView-BYKQXHHe.js → ForgotMyPasswordView-CPC4cOzo.js} +3 -3
- package/dist/assets/{InfoAccordion-DN17_QNh.js → InfoAccordion-M_n3OwQC.js} +1 -1
- package/dist/assets/{InsightsChartAverageRuntime-DX6MWomC.js → InsightsChartAverageRuntime-CECRGvo9.js} +4 -4
- package/dist/assets/{InsightsChartFailed-D1ITW7ip.js → InsightsChartFailed-CTysIk94.js} +4 -4
- package/dist/assets/{InsightsChartFailureRate-DsoCFhrx.js → InsightsChartFailureRate-LYCt3dgO.js} +4 -4
- package/dist/assets/{InsightsChartTimeSaved-Cwb0-EZ1.js → InsightsChartTimeSaved-msRVtM_g.js} +4 -4
- package/dist/assets/{InsightsChartTotal-B-SjjDG4.js → InsightsChartTotal-B_SUDPoP.js} +4 -4
- package/dist/assets/{InsightsDashboard-DEaMMGfn.js → InsightsDashboard-CEgagMwD.js} +10 -10
- package/dist/assets/{InsightsPaywall-BsiLaxNd.js → InsightsPaywall-EnxDs7BF.js} +1 -1
- package/dist/assets/{InsightsSummary-hBcY77J_.js → InsightsSummary-DWzNYCfc.js} +1 -1
- package/dist/assets/{InsightsTableWorkflows-D9vFPmUm.js → InsightsTableWorkflows-Dl55NtXk.js} +5 -5
- package/dist/assets/{Logo-D-nqGbZ-.js → Logo-MNn4rP0b.js} +1 -1
- package/dist/assets/{LogsPanel-D0xdq4fV.css → LogsPanel-B-Tmod-K.css} +25 -22
- package/dist/assets/{LogsPanel-D0QGW50a.js → LogsPanel-DN3BXSh7.js} +209 -51
- package/dist/assets/{MainHeader-QpSmh7DV.js → MainHeader-F9ONi2FH.js} +8 -10
- package/dist/assets/{MainSidebar-Dndr9Vcx.js → MainSidebar-Bf58ZTkX.js} +2 -3
- package/dist/assets/{N8nDataTableServer-B4Gq_Urn.js → N8nDataTableServer-PFDwZhpw.js} +1 -1
- package/dist/assets/{NodeCreation-CRGHu2mV.js → NodeCreation-B9FRFHG0.js} +16 -13
- package/dist/assets/{NodeCreator-BvleRmX-.js → NodeCreator-nBzvpVJI.js} +11 -20
- package/dist/assets/{NodeDetailsView-xvbRzTfv.js → NodeDetailsView-CQQOZQXq.js} +13 -17
- package/dist/assets/{NodeDetailsViewV2-CBY4UJcE.js → NodeDetailsViewV2-DKnduvJH.js} +27 -31
- package/dist/assets/{NodeDetailsViewV2-BxNx4ZUM.css → NodeDetailsViewV2-LLVofUjw.css} +21 -19
- package/dist/assets/NodeView-B2097MY0.css +852 -0
- package/dist/assets/NodeView-rsVaGRIZ.js +2684 -0
- package/dist/assets/{ProjectHeader-0NxiEwQl.js → ProjectHeader-B8m2WaGw.js} +2 -2
- package/dist/assets/{ProjectSettings-ClM6Y9uS.js → ProjectSettings-CKIJ3B4S.js} +3 -3
- package/dist/assets/{PushConnectionTracker.vue_vue_type_script_setup_true_lang-D5JeFl_d.js → PushConnectionTracker.vue_vue_type_script_setup_true_lang-D5oQ44UZ.js} +1 -1
- package/dist/assets/{ResourcesListLayout-BRro9C-1.js → ResourcesListLayout-G2r5AxKI.js} +3 -3
- package/dist/assets/{RunDataJson-12Py20Rs.js → RunDataJson-CAcnDJHh.js} +3 -6
- package/dist/assets/{RunDataJsonActions-BGl8YYU0.js → RunDataJsonActions-jhh18-uN.js} +13 -13
- package/dist/assets/{RunDataParsedAiContent-DYz5OPxJ.js → RunDataParsedAiContent-B8wa1hGI.js} +25 -11
- package/dist/assets/{RunDataSearch-NmwtxOjZ.js → RunDataSearch-CFmNTJ3I.js} +1 -1
- package/dist/assets/{RunDataTable-DJu8Ut0r.js → RunDataTable-91h3y7DT.js} +1 -2
- package/dist/assets/{SamlOnboarding-B5vqtns9.js → SamlOnboarding-8Gb7hf0c.js} +3 -3
- package/dist/assets/{SettingsApiView-DmOvPlm6.js → SettingsApiView-BozlwAdS.js} +1 -1
- package/dist/assets/{SettingsCommunityNodesView-DEgzWHlF.js → SettingsCommunityNodesView-RlNbis18.js} +4 -4
- package/dist/assets/{SettingsExternalSecrets-4VNCsQKo.js → SettingsExternalSecrets-Blou_9Mh.js} +1 -1
- package/dist/assets/{SettingsLdapView-BSQe5yy-.js → SettingsLdapView-wf-fX_Jl.js} +1 -1
- package/dist/assets/{SettingsLogStreamingView-Y-ve-MUB.js → SettingsLogStreamingView-DNaMOOjb.js} +1 -1
- package/dist/assets/{SettingsPersonalView-DTWO2GIc.js → SettingsPersonalView-DzYhwUgL.js} +1 -1
- package/dist/assets/{SettingsSourceControl-D14mBzgS.js → SettingsSourceControl-D5eiGsMG.js} +1 -1
- package/dist/assets/{SettingsSso-Beon1K6u.js → SettingsSso-BF8vNEd4.js} +7 -12
- package/dist/assets/{SettingsUsageAndPlan-hc6EFbHM.js → SettingsUsageAndPlan-Di_gUxTt.js} +1 -1
- package/dist/assets/{SettingsUsersView-CIzwxl6-.js → SettingsUsersView-BDNxV1rM.js} +2 -3
- package/dist/assets/{SettingsView-Bv-AL-MH.js → SettingsView-CAaXgrDd.js} +1 -1
- package/dist/assets/{SetupView-BCKg0AbF.js → SetupView-DIO89PJN.js} +3 -3
- package/dist/assets/{SetupWorkflowCredentialsButton-djsoNbvZ.js → SetupWorkflowCredentialsButton-y92onTNS.js} +1 -1
- package/dist/assets/{SetupWorkflowFromTemplateView-CZhYUSco.js → SetupWorkflowFromTemplateView-Hnqry6sO.js} +3 -3
- package/dist/assets/{SigninView-BPl0jjB0.js → SigninView-t0q2CjNU.js} +3 -3
- package/dist/assets/{SignoutView-BHPz3HFX.js → SignoutView-DjCS-jDi.js} +1 -1
- package/dist/assets/{SignupView-Cel8_b46.js → SignupView-BoEH4AVN.js} +3 -3
- package/dist/assets/{TableBase-BIT7ArUw.js → TableBase-D-1VfIgb.js} +1 -1
- package/dist/assets/{Tags-CQIEP_IZ.js → Tags-CnT3a0bf.js} +1 -1
- package/dist/assets/{TemplateDetails-B8u34j2l.js → TemplateDetails-B-tHb3Wq.js} +4 -4
- package/dist/assets/{TemplateList-BJSJYiHs.js → TemplateList-j7v4XLCo.js} +3 -3
- package/dist/assets/{TemplatesCollectionView-BCAAV1n9.js → TemplatesCollectionView-BPxSoEA5.js} +6 -6
- package/dist/assets/{TemplatesSearchView-CXOrNnyk.js → TemplatesSearchView-kZfygKcP.js} +3 -3
- package/dist/assets/{TemplatesView-1HunP4nN.js → TemplatesView-KQ5r6RZF.js} +2 -2
- package/dist/assets/{TemplatesWorkflowView-0enp4pR7.js → TemplatesWorkflowView-Pdm_DUrH.js} +6 -6
- package/dist/assets/{TriggerPanel-B-Jt4r3F.js → TriggerPanel-WYRtg2P1.js} +39 -29
- package/dist/assets/{TriggerPanel-DJv04feX.css → TriggerPanel-gMtmEr6n.css} +16 -13
- package/dist/assets/{VariablesView-mSWZzDyf.js → VariablesView-CdihBrCp.js} +5 -5
- package/dist/assets/{VueMarkdown-Dxf59_T_.js → VueMarkdown-CLlUve9b.js} +1 -1
- package/dist/assets/{WorkerView-DbqNyqok.js → WorkerView-C_q2Cgtl.js} +6 -6
- package/dist/assets/{WorkflowActivator-C33REd8m.js → WorkflowActivator-CDlyaU2W.js} +2 -2
- package/dist/assets/{WorkflowExecutionsInfoAccordion-CCe9jbiT.js → WorkflowExecutionsInfoAccordion-1aoYaoWj.js} +2 -2
- package/dist/assets/{WorkflowExecutionsLandingPage-DMXVsIHS.js → WorkflowExecutionsLandingPage-Cuz4EdsV.js} +3 -3
- package/dist/assets/{WorkflowExecutionsPreview-Dit3_l9q.js → WorkflowExecutionsPreview-BmDk9pdW.js} +7 -6
- package/dist/assets/{WorkflowExecutionsView-BwLTPvQ7.js → WorkflowExecutionsView-ClPpGdce.js} +6 -8
- package/dist/assets/{WorkflowHistory-BgNzJgze.js → WorkflowHistory-EoRsFrnu.js} +2 -3
- package/dist/assets/{WorkflowOnboardingView-Bnvmd6lJ.js → WorkflowOnboardingView-B4DUomvQ.js} +1 -1
- package/dist/assets/{WorkflowPreview-DIDMhnNP.js → WorkflowPreview-dQweS-xu.js} +1 -1
- package/dist/assets/{WorkflowsView-DxtULRby.js → WorkflowsView-DQJRBDtq.js} +275 -30
- package/dist/assets/{WorkflowsView-CyJbJBc8.css → WorkflowsView-DsJIOJ7h.css} +263 -0
- package/dist/assets/{aiTemplatesStarterCollection.store-DrHWcqtc.js → aiTemplatesStarterCollection.store-CTW_MDA8.js} +1 -1
- package/dist/assets/canvas-CMXo2Bja.js +5 -0
- package/dist/assets/{chartjs.utils-DQHNgzzp.js → chartjs.utils-CHvsojzm.js} +2 -2
- package/dist/assets/{en-BX7CKkqE.js → en-D7cJPQEa.js} +22 -2
- package/dist/assets/{global-link-actions-DzXrk-LO.js → global-link-actions-BxO50hoE.js} +1 -1
- package/dist/assets/{index-BWpYwmXd.css → index-BwGKZdwg.css} +15180 -4281
- package/dist/assets/{index-BmZCxv8-.js → index-DycvFkIw.js} +62280 -30323
- package/dist/assets/{index-x7t8iCsI.js → index-T1FYm0tg.js} +1 -1
- package/dist/assets/{pickBy-oHD63WOf.js → pickBy-DMiUcEKW.js} +1 -1
- package/dist/assets/{polyfills-B8p9DdqU.js → polyfills-eMEFRc79.js} +0 -32
- package/dist/assets/{templateActions-_QLqrCsm.js → templateActions-DrHAzjmQ.js} +1 -1
- package/dist/assets/{useBeforeUnload-CBmJdmlS.js → useBeforeUnload-uDmDsya_.js} +1 -1
- package/dist/assets/{useExecutionDebugging-B22Oj62X.js → useExecutionDebugging-wqUkD23F.js} +1 -1
- package/dist/assets/{useImportCurlCommand-CCUM_iVn.js → useImportCurlCommand-CBZG4Lbx.js} +1 -2
- package/dist/assets/{useProjectPages-CrI3xlbd.js → useProjectPages-CW2fEpJH.js} +1 -1
- package/dist/assets/{usePushConnection-EYkv1Xyg.js → usePushConnection-BM5QyJob.js} +3 -3
- package/dist/assets/{useWorkflowActivate-BiorS_mB.js → useWorkflowActivate-Dw_VspVF.js} +1 -1
- package/dist/index.html +5 -5
- package/dist/static/posthog.init.js +41 -0
- package/dist/static/prefers-color-scheme.css +5 -0
- package/index.html +2 -2
- package/package.json +1 -1
- package/tsconfig.json +1 -0
- package/dist/assets/ActionDropdown-BmC0wfMx.css +0 -172
- package/dist/assets/ActionDropdown-DkHCqhLi.js +0 -172
- package/dist/assets/CollectionParameter-C3JIvBsy.js +0 -4
- package/dist/assets/FileSaver.min-CiFUM_59.js +0 -81
- package/dist/assets/NodeView-Dm74W6kN.js +0 -18815
- package/dist/assets/NodeView-G2qfXaOy.css +0 -7402
- package/dist/assets/import-curl-BrVSOGQW.js +0 -5
- package/dist/assets/useExecutionHelpers-C6meisqx.js +0 -94
- package/dist/assets/useKeybindings-2A271Jke.css +0 -2007
- package/dist/assets/useKeybindings-CcHEvN6i.js +0 -3627
|
@@ -0,0 +1,2684 @@
|
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/NodeCreation-B9FRFHG0.js","assets/index-DycvFkIw.js","assets/index-BwGKZdwg.css","assets/NodeCreation-CxN6JIS_.css","assets/NodeDetailsView-CQQOZQXq.js","assets/TriggerPanel-WYRtg2P1.js","assets/RunDataParsedAiContent-B8wa1hGI.js","assets/VueMarkdown-CLlUve9b.js","assets/RunDataParsedAiContent-wfIiKsq7.css","assets/ConsumedTokensDetails.vue_vue_type_script_setup_true_lang-DIcGPKiM.js","assets/InfoAccordion-M_n3OwQC.js","assets/InfoAccordion-dxudNqVC.css","assets/TriggerPanel-gMtmEr6n.css","assets/useWorkflowActivate-Dw_VspVF.js","assets/global-link-actions-BxO50hoE.js","assets/useExecutionDebugging-wqUkD23F.js","assets/useBeforeUnload-uDmDsya_.js","assets/canvas-CMXo2Bja.js","assets/aiTemplatesStarterCollection.store-CTW_MDA8.js","assets/NodeDetailsView-CaTI-1QQ.css","assets/NodeDetailsViewV2-DKnduvJH.js","assets/NodeDetailsViewV2-LLVofUjw.css","assets/SetupWorkflowCredentialsButton-y92onTNS.js"])))=>i.map(i=>d[i]);
|
|
2
|
+
import { d as defineComponent, x as computed, r as ref, aP as useNDVStore, ab as watch, h as createElementBlock, g as openBlock, n as normalizeClass, e as createBlock, f as createCommentVNode, l as unref, p as N8nText, w as withCtx, k as createTextVNode, t as toDisplayString, cs as _sfc_main$9, i as createVNode, a0 as _sfc_main$a, _ as _export_sfc, Q as createEventBus, ac as useCssModule, v as useSettingsStore, ct as useVueFlow, bW as toRef, cu as useCanvasMapping, cv as refThrottled, j as createBaseVNode, J as renderSlot, cw as Canvas, D as mergeProps, a5 as useWorkflowsStore, bF as useNodeHelpers, cx as useFocusPanelStore, bK as useNodeTypesStore, cy as useNodeSettingsParameters, cz as useEnvironmentsStore, cA as useDeviceSupport, S as useDebounce, cB as HTML_NODE_TYPE, cC as isValueExpression, cD as isResourceLocatorValue, cE as AI_TRANSFORM_NODE_TYPE, cF as useResolvedExpression, cf as useThrottleFn, bS as withModifiers, cG as _sfc_main$b, N as N8nIcon, cH as InfoTip, c as useI18n, cI as __unplugin_components_2, cJ as __unplugin_components_3, F as Fragment, cK as __unplugin_components_4, cL as __unplugin_components_5, cM as __unplugin_components_6, cN as __unplugin_components_7, cO as __unplugin_components_8, cP as __unplugin_components_9, cQ as N8nInput, H as N8nRadioButtons, P as normalizeStyle, cd as useStyles, cc as N8nResizeWrapper, cR as getParameterTypeOption, cS as htmlEditorEventBus, cT as parseFromExpression, cU as isValidParameterOption, cV as formatAsExpression, aA as useTelemetry, K as nextTick, cW as hasFocusOnInput, cX as isFocusableEl, br as isChatNode, cY as truncateBeforeLast, q as N8nButton, a1 as I18nT, cb as KeyboardShortcutTooltip, bT as NodeIcon, ay as N8nActionDropdown, cZ as reactive, o as onMounted, c2 as onUnmounted, b as useRouter, a6 as useRoute, a as useToast, aj as useDocumentTitle, al as useWorkflowHelpers, ak as useWorkflowSaving, T as useUIStore, af as useSourceControlStore, c_ as useNodeCreatorStore, c$ as useCredentialsStore, d0 as useExternalSecretsStore, ad as useRootStore, aQ as useExecutionsStore, ae as useCanvasStore, ai as useNpsSurveyStore, d1 as useHistoryStore, ag as useProjectsStore, u as useUsersStore, R as useTagsStore, a4 as usePushConnectionStore, be as useTemplatesStore, d2 as useBuilderStore, ah as useFoldersStore, d3 as usePostHog, d4 as useAgentRequestStore, bE as useLogsStore, bG as useRunWorkflow, bJ as useCanvasOperations, d5 as useWorkflowExtraction, c5 as useClipboard, a7 as PLACEHOLDER_EMPTY_WORKFLOW_ID, d6 as NEW_WORKFLOW_ID, V as VIEWS, d7 as NDV_UI_OVERHAUL_EXPERIMENT, bL as START_NODE_TYPE, d8 as getNodeViewTab, G as MAIN_HEADER_TABS, d9 as VALID_WORKFLOW_IMPORT_URL_REGEX, aC as useMessage, aD as MODAL_CONFIRM, da as jsonParse, an as getResourcePermissions, bB as CHAT_TRIGGER_NODE_TYPE, bA as MANUAL_CHAT_TRIGGER_NODE_TYPE, db as EVALUATION_TRIGGER_NODE_TYPE, dc as getBounds, dd as onBeforeRouteLeave, aU as onBeforeMount, aE as WORKFLOW_SETTINGS_MODAL_KEY, bg as useExternalHooks, de as onActivated, df as onDeactivated, I as onBeforeUnmount, dg as Suspense, dh as defineAsyncComponent, di as N8nCallout, aL as __vitePreload, aq as EnterpriseEditionFeature, dj as NODE_CREATOR_OPEN_SOURCES, dk as EVALUATION_NODE_TYPE, dl as getEasyAiWorkflowJson, dm as getRagStarterWorkflowJson, dn as tryToParseNumber, aB as nodeViewEventBus, bs as NodeConnectionTypes, dp as createCanvasConnectionHandleString, dq as isValidNodeConnectionType, dr as CanvasConnectionMode, b4 as sourceControlEventBus, ds as getNodesWithNormalizedPosition, aN as h, dt as CanvasNodeRenderType, aT as STICKY_NODE_TYPE, du as needsAgentInput, dv as FROM_AI_PARAMETERS_MODAL_KEY, dw as historyBus, dx as DRAG_EVENT_DATA_KEY } from "./index-DycvFkIw.js";
|
|
3
|
+
import { g as globalLinkActionsEventBus } from "./global-link-actions-BxO50hoE.js";
|
|
4
|
+
import { u as useExecutionDebugging } from "./useExecutionDebugging-wqUkD23F.js";
|
|
5
|
+
import { u as useBeforeUnload } from "./useBeforeUnload-uDmDsya_.js";
|
|
6
|
+
import { c as canvasEventBus } from "./canvas-CMXo2Bja.js";
|
|
7
|
+
import { u as useAITemplatesStarterCollectionStore } from "./aiTemplatesStarterCollection.store-CTW_MDA8.js";
|
|
8
|
+
const _sfc_main$8 = /* @__PURE__ */ defineComponent({
|
|
9
|
+
__name: "ExperimentalNodeDetailsDrawer",
|
|
10
|
+
props: {
|
|
11
|
+
selectedNodes: {}
|
|
12
|
+
},
|
|
13
|
+
setup(__props) {
|
|
14
|
+
const content2 = computed(
|
|
15
|
+
() => __props.selectedNodes.length > 1 ? `${__props.selectedNodes.length} nodes selected` : __props.selectedNodes.length > 0 ? __props.selectedNodes[0] : void 0
|
|
16
|
+
);
|
|
17
|
+
const lastContent = ref();
|
|
18
|
+
const { setActiveNodeName } = useNDVStore();
|
|
19
|
+
function handleOpenNdv() {
|
|
20
|
+
if (typeof content2.value === "object" && content2.value.data) {
|
|
21
|
+
setActiveNodeName(content2.value.data.name);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
watch(
|
|
25
|
+
content2,
|
|
26
|
+
(newContent) => {
|
|
27
|
+
if (newContent !== void 0) {
|
|
28
|
+
lastContent.value = newContent;
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
{ immediate: true }
|
|
32
|
+
);
|
|
33
|
+
return (_ctx, _cache) => {
|
|
34
|
+
const _component_N8nIconButton = _sfc_main$a;
|
|
35
|
+
return openBlock(), createElementBlock("div", {
|
|
36
|
+
class: normalizeClass([_ctx.$style.component, content2.value === void 0 ? _ctx.$style.closed : ""])
|
|
37
|
+
}, [
|
|
38
|
+
typeof lastContent.value === "string" ? (openBlock(), createBlock(unref(N8nText), {
|
|
39
|
+
key: 0,
|
|
40
|
+
color: "text-base"
|
|
41
|
+
}, {
|
|
42
|
+
default: withCtx(() => [
|
|
43
|
+
createTextVNode(toDisplayString(lastContent.value), 1)
|
|
44
|
+
]),
|
|
45
|
+
_: 1
|
|
46
|
+
})) : lastContent.value !== void 0 ? (openBlock(), createBlock(_sfc_main$9, {
|
|
47
|
+
key: lastContent.value.id,
|
|
48
|
+
"node-id": lastContent.value.id
|
|
49
|
+
}, {
|
|
50
|
+
actions: withCtx(() => [
|
|
51
|
+
createVNode(_component_N8nIconButton, {
|
|
52
|
+
icon: "maximize-2",
|
|
53
|
+
type: "secondary",
|
|
54
|
+
text: "",
|
|
55
|
+
size: "mini",
|
|
56
|
+
"icon-size": "large",
|
|
57
|
+
"aria-label": "Expand",
|
|
58
|
+
onClick: handleOpenNdv
|
|
59
|
+
})
|
|
60
|
+
]),
|
|
61
|
+
_: 1
|
|
62
|
+
}, 8, ["node-id"])) : createCommentVNode("", true)
|
|
63
|
+
], 2);
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
const component$1 = "_component_wojby_123";
|
|
68
|
+
const closed = "_closed_wojby_138";
|
|
69
|
+
const style0$4 = {
|
|
70
|
+
component: component$1,
|
|
71
|
+
closed
|
|
72
|
+
};
|
|
73
|
+
const cssModules$4 = {
|
|
74
|
+
"$style": style0$4
|
|
75
|
+
};
|
|
76
|
+
const ExperimentalNodeDetailsDrawer = /* @__PURE__ */ _export_sfc(_sfc_main$8, [["__cssModules", cssModules$4]]);
|
|
77
|
+
const _sfc_main$7 = /* @__PURE__ */ defineComponent({
|
|
78
|
+
...{
|
|
79
|
+
inheritAttrs: false
|
|
80
|
+
},
|
|
81
|
+
__name: "WorkflowCanvas",
|
|
82
|
+
props: {
|
|
83
|
+
id: { default: "canvas" },
|
|
84
|
+
workflow: {},
|
|
85
|
+
workflowObject: {},
|
|
86
|
+
fallbackNodes: { default: () => [] },
|
|
87
|
+
showFallbackNodes: { type: Boolean, default: true },
|
|
88
|
+
eventBus: { default: () => createEventBus() },
|
|
89
|
+
readOnly: { type: Boolean },
|
|
90
|
+
executing: { type: Boolean }
|
|
91
|
+
},
|
|
92
|
+
setup(__props) {
|
|
93
|
+
const props = __props;
|
|
94
|
+
const $style = useCssModule();
|
|
95
|
+
const settingsStore = useSettingsStore();
|
|
96
|
+
const { onNodesInitialized, getSelectedNodes } = useVueFlow(props.id);
|
|
97
|
+
const workflow = toRef(props, "workflow");
|
|
98
|
+
const workflowObject = toRef(props, "workflowObject");
|
|
99
|
+
const nodes = computed(() => {
|
|
100
|
+
return props.showFallbackNodes ? [...props.workflow.nodes, ...props.fallbackNodes] : props.workflow.nodes;
|
|
101
|
+
});
|
|
102
|
+
const connections = computed(() => props.workflow.connections);
|
|
103
|
+
const { nodes: mappedNodes, connections: mappedConnections } = useCanvasMapping({
|
|
104
|
+
nodes,
|
|
105
|
+
connections,
|
|
106
|
+
workflowObject
|
|
107
|
+
});
|
|
108
|
+
const initialFitViewDone = ref(false);
|
|
109
|
+
onNodesInitialized(() => {
|
|
110
|
+
if (!initialFitViewDone.value || props.showFallbackNodes) {
|
|
111
|
+
props.eventBus.emit("fitView");
|
|
112
|
+
initialFitViewDone.value = true;
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
const mappedNodesThrottled = refThrottled(mappedNodes, 200);
|
|
116
|
+
const mappedConnectionsThrottled = refThrottled(mappedConnections, 200);
|
|
117
|
+
return (_ctx, _cache) => {
|
|
118
|
+
return openBlock(), createElementBlock("div", {
|
|
119
|
+
class: normalizeClass(unref($style).wrapper),
|
|
120
|
+
"data-test-id": "canvas-wrapper"
|
|
121
|
+
}, [
|
|
122
|
+
createBaseVNode("div", {
|
|
123
|
+
class: normalizeClass(unref($style).canvas)
|
|
124
|
+
}, [
|
|
125
|
+
workflow.value ? (openBlock(), createBlock(Canvas, mergeProps({
|
|
126
|
+
key: 0,
|
|
127
|
+
id: _ctx.id,
|
|
128
|
+
nodes: _ctx.executing ? unref(mappedNodesThrottled) : unref(mappedNodes),
|
|
129
|
+
connections: _ctx.executing ? unref(mappedConnectionsThrottled) : unref(mappedConnections),
|
|
130
|
+
"event-bus": _ctx.eventBus,
|
|
131
|
+
"read-only": _ctx.readOnly,
|
|
132
|
+
executing: _ctx.executing
|
|
133
|
+
}, _ctx.$attrs), null, 16, ["id", "nodes", "connections", "event-bus", "read-only", "executing"])) : createCommentVNode("", true)
|
|
134
|
+
], 2),
|
|
135
|
+
renderSlot(_ctx.$slots, "default"),
|
|
136
|
+
unref(settingsStore).experimental__dockedNodeSettingsEnabled && !props.readOnly ? (openBlock(), createBlock(ExperimentalNodeDetailsDrawer, {
|
|
137
|
+
key: 0,
|
|
138
|
+
"selected-nodes": unref(getSelectedNodes)
|
|
139
|
+
}, null, 8, ["selected-nodes"])) : createCommentVNode("", true)
|
|
140
|
+
], 2);
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
const wrapper$2 = "_wrapper_jyurh_123";
|
|
145
|
+
const canvas = "_canvas_jyurh_131";
|
|
146
|
+
const style0$3 = {
|
|
147
|
+
wrapper: wrapper$2,
|
|
148
|
+
canvas
|
|
149
|
+
};
|
|
150
|
+
const cssModules$3 = {
|
|
151
|
+
"$style": style0$3
|
|
152
|
+
};
|
|
153
|
+
const WorkflowCanvas = /* @__PURE__ */ _export_sfc(_sfc_main$7, [["__cssModules", cssModules$3]]);
|
|
154
|
+
function useExecutionData({ node }) {
|
|
155
|
+
const workflowsStore = useWorkflowsStore();
|
|
156
|
+
const workflowExecution = computed(() => {
|
|
157
|
+
return workflowsStore.getWorkflowExecution;
|
|
158
|
+
});
|
|
159
|
+
const workflowRunData = computed(() => {
|
|
160
|
+
if (workflowExecution.value === null) {
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
const executionData = workflowExecution.value.data;
|
|
164
|
+
if (!executionData?.resultData?.runData) {
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
167
|
+
return executionData.resultData.runData;
|
|
168
|
+
});
|
|
169
|
+
const hasNodeRun = computed(() => {
|
|
170
|
+
if (workflowsStore.subWorkflowExecutionError) return true;
|
|
171
|
+
return Boolean(
|
|
172
|
+
node.value && workflowRunData.value && Object.prototype.hasOwnProperty.bind(workflowRunData.value)(node.value.name)
|
|
173
|
+
);
|
|
174
|
+
});
|
|
175
|
+
return {
|
|
176
|
+
workflowExecution,
|
|
177
|
+
workflowRunData,
|
|
178
|
+
hasNodeRun
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
const _sfc_main$6 = /* @__PURE__ */ defineComponent({
|
|
182
|
+
...{ name: "FocusPanel" },
|
|
183
|
+
__name: "FocusPanel",
|
|
184
|
+
props: {
|
|
185
|
+
isCanvasReadOnly: { type: Boolean }
|
|
186
|
+
},
|
|
187
|
+
emits: ["focus", "saveKeyboardShortcut"],
|
|
188
|
+
setup(__props, { emit: __emit }) {
|
|
189
|
+
const props = __props;
|
|
190
|
+
const emit = __emit;
|
|
191
|
+
const inputField = ref();
|
|
192
|
+
const locale = useI18n();
|
|
193
|
+
const nodeHelpers = useNodeHelpers();
|
|
194
|
+
const focusPanelStore = useFocusPanelStore();
|
|
195
|
+
const workflowsStore = useWorkflowsStore();
|
|
196
|
+
const nodeTypesStore = useNodeTypesStore();
|
|
197
|
+
const telemetry = useTelemetry();
|
|
198
|
+
const nodeSettingsParameters = useNodeSettingsParameters();
|
|
199
|
+
const environmentsStore = useEnvironmentsStore();
|
|
200
|
+
const deviceSupport = useDeviceSupport();
|
|
201
|
+
const { debounce } = useDebounce();
|
|
202
|
+
const styles = useStyles();
|
|
203
|
+
const focusedNodeParameter = computed(() => focusPanelStore.focusedNodeParameters[0]);
|
|
204
|
+
const resolvedParameter = computed(
|
|
205
|
+
() => focusedNodeParameter.value && focusPanelStore.isRichParameter(focusedNodeParameter.value) ? focusedNodeParameter.value : void 0
|
|
206
|
+
);
|
|
207
|
+
const focusPanelActive = computed(() => focusPanelStore.focusPanelActive);
|
|
208
|
+
const focusPanelWidth = computed(() => focusPanelStore.focusPanelWidth);
|
|
209
|
+
const isDisabled = computed(() => {
|
|
210
|
+
if (!resolvedParameter.value) return false;
|
|
211
|
+
return !!resolvedParameter.value.parameter.disabledOptions && nodeSettingsParameters.shouldDisplayNodeParameter(
|
|
212
|
+
resolvedParameter.value.node.parameters,
|
|
213
|
+
resolvedParameter.value.node,
|
|
214
|
+
resolvedParameter.value.parameter,
|
|
215
|
+
resolvedParameter.value.parameterPath.split(".").slice(1, -1).join("."),
|
|
216
|
+
"disabledOptions"
|
|
217
|
+
);
|
|
218
|
+
});
|
|
219
|
+
const isDisplayed = computed(() => {
|
|
220
|
+
if (!resolvedParameter.value) return true;
|
|
221
|
+
return nodeSettingsParameters.shouldDisplayNodeParameter(
|
|
222
|
+
resolvedParameter.value.node.parameters,
|
|
223
|
+
resolvedParameter.value.node,
|
|
224
|
+
resolvedParameter.value.parameter,
|
|
225
|
+
resolvedParameter.value.parameterPath.split(".").slice(1, -1).join("."),
|
|
226
|
+
"displayOptions"
|
|
227
|
+
);
|
|
228
|
+
});
|
|
229
|
+
const isExecutable = computed(() => {
|
|
230
|
+
if (!resolvedParameter.value) return false;
|
|
231
|
+
if (!isDisplayed.value) return false;
|
|
232
|
+
const foreignCredentials = nodeHelpers.getForeignCredentialsIfSharingEnabled(
|
|
233
|
+
resolvedParameter.value.node.credentials
|
|
234
|
+
);
|
|
235
|
+
return nodeHelpers.isNodeExecutable(
|
|
236
|
+
resolvedParameter.value.node,
|
|
237
|
+
!props.isCanvasReadOnly,
|
|
238
|
+
foreignCredentials
|
|
239
|
+
);
|
|
240
|
+
});
|
|
241
|
+
const node = computed(() => resolvedParameter.value?.node);
|
|
242
|
+
const { workflowRunData } = useExecutionData({ node });
|
|
243
|
+
const hasNodeRun = computed(() => {
|
|
244
|
+
if (!node.value) return true;
|
|
245
|
+
const parentNode = workflowsStore.getCurrentWorkflow().getParentNodes(node.value.name, "main", 1)[0];
|
|
246
|
+
return Boolean(
|
|
247
|
+
parentNode && workflowRunData.value && Object.prototype.hasOwnProperty.bind(workflowRunData.value)(parentNode)
|
|
248
|
+
);
|
|
249
|
+
});
|
|
250
|
+
function getTypeOption(optionName) {
|
|
251
|
+
return resolvedParameter.value ? getParameterTypeOption(resolvedParameter.value.parameter, optionName) : void 0;
|
|
252
|
+
}
|
|
253
|
+
const codeEditorMode = computed(() => {
|
|
254
|
+
return resolvedParameter.value?.node.parameters.mode;
|
|
255
|
+
});
|
|
256
|
+
const editorType = computed(() => {
|
|
257
|
+
return getTypeOption("editor") ?? void 0;
|
|
258
|
+
});
|
|
259
|
+
const editorLanguage = computed(() => {
|
|
260
|
+
if (editorType.value === "json" || resolvedParameter.value?.parameter.type === "json")
|
|
261
|
+
return "json";
|
|
262
|
+
return getTypeOption("editorLanguage") ?? "javaScript";
|
|
263
|
+
});
|
|
264
|
+
const editorRows = computed(() => getTypeOption("rows"));
|
|
265
|
+
const isToolNode = computed(
|
|
266
|
+
() => resolvedParameter.value ? nodeTypesStore.isToolNode(resolvedParameter.value?.node.type) : false
|
|
267
|
+
);
|
|
268
|
+
const isHtmlNode = computed(
|
|
269
|
+
() => !!resolvedParameter.value && resolvedParameter.value.node.type === HTML_NODE_TYPE
|
|
270
|
+
);
|
|
271
|
+
const expressionModeEnabled = computed(
|
|
272
|
+
() => resolvedParameter.value && isValueExpression(resolvedParameter.value.parameter, resolvedParameter.value.value)
|
|
273
|
+
);
|
|
274
|
+
const expression = computed(() => {
|
|
275
|
+
if (!expressionModeEnabled.value) return "";
|
|
276
|
+
return isResourceLocatorValue(resolvedParameter.value) ? resolvedParameter.value.value : resolvedParameter.value;
|
|
277
|
+
});
|
|
278
|
+
const shouldCaptureForPosthog = computed(
|
|
279
|
+
() => resolvedParameter.value?.node.type === AI_TRANSFORM_NODE_TYPE
|
|
280
|
+
);
|
|
281
|
+
const isReadOnly = computed(() => props.isCanvasReadOnly || isDisabled.value);
|
|
282
|
+
const resolvedAdditionalExpressionData = computed(() => {
|
|
283
|
+
return {
|
|
284
|
+
$vars: environmentsStore.variablesAsObject
|
|
285
|
+
};
|
|
286
|
+
});
|
|
287
|
+
const targetNodeParameterContext = computed(() => {
|
|
288
|
+
if (!resolvedParameter.value) return void 0;
|
|
289
|
+
return {
|
|
290
|
+
nodeName: resolvedParameter.value.node.name,
|
|
291
|
+
parameterPath: resolvedParameter.value.parameterPath
|
|
292
|
+
};
|
|
293
|
+
});
|
|
294
|
+
const isNodeExecuting = computed(() => workflowsStore.isNodeExecuting(node.value?.name ?? ""));
|
|
295
|
+
const { resolvedExpression } = useResolvedExpression({
|
|
296
|
+
expression,
|
|
297
|
+
additionalData: resolvedAdditionalExpressionData,
|
|
298
|
+
stringifyObject: resolvedParameter.value && resolvedParameter.value.parameter.type !== "multiOptions"
|
|
299
|
+
});
|
|
300
|
+
function valueChanged(value) {
|
|
301
|
+
if (resolvedParameter.value === void 0) {
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
nodeSettingsParameters.updateNodeParameter(
|
|
305
|
+
toRef(resolvedParameter.value.node.parameters),
|
|
306
|
+
{ value, name: resolvedParameter.value.parameterPath },
|
|
307
|
+
value,
|
|
308
|
+
resolvedParameter.value.node,
|
|
309
|
+
isToolNode.value
|
|
310
|
+
);
|
|
311
|
+
}
|
|
312
|
+
async function setFocus() {
|
|
313
|
+
await nextTick();
|
|
314
|
+
if (inputField.value) {
|
|
315
|
+
if (hasFocusOnInput(inputField.value)) {
|
|
316
|
+
inputField.value.focusOnInput();
|
|
317
|
+
} else if (isFocusableEl(inputField.value)) {
|
|
318
|
+
inputField.value.focus();
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
emit("focus");
|
|
322
|
+
}
|
|
323
|
+
function optionSelected(command) {
|
|
324
|
+
if (!resolvedParameter.value) return;
|
|
325
|
+
switch (command) {
|
|
326
|
+
case "resetValue": {
|
|
327
|
+
if (typeof resolvedParameter.value.parameter.default === "string") {
|
|
328
|
+
valueChanged(resolvedParameter.value.parameter.default);
|
|
329
|
+
}
|
|
330
|
+
void setFocus();
|
|
331
|
+
break;
|
|
332
|
+
}
|
|
333
|
+
case "addExpression": {
|
|
334
|
+
const newValue = formatAsExpression(
|
|
335
|
+
resolvedParameter.value.value,
|
|
336
|
+
resolvedParameter.value.parameter.type
|
|
337
|
+
);
|
|
338
|
+
valueChanged(typeof newValue === "string" ? newValue : newValue.value);
|
|
339
|
+
void setFocus();
|
|
340
|
+
break;
|
|
341
|
+
}
|
|
342
|
+
case "removeExpression": {
|
|
343
|
+
const newValue = parseFromExpression(
|
|
344
|
+
resolvedParameter.value.value,
|
|
345
|
+
resolvedExpression.value,
|
|
346
|
+
resolvedParameter.value.parameter.type,
|
|
347
|
+
resolvedParameter.value.parameter.default,
|
|
348
|
+
(resolvedParameter.value.parameter.options ?? []).filter(isValidParameterOption)
|
|
349
|
+
);
|
|
350
|
+
if (typeof newValue === "string") {
|
|
351
|
+
valueChanged(newValue);
|
|
352
|
+
} else if (newValue && typeof newValue.value === "string") {
|
|
353
|
+
valueChanged(newValue.value);
|
|
354
|
+
}
|
|
355
|
+
void setFocus();
|
|
356
|
+
break;
|
|
357
|
+
}
|
|
358
|
+
case "formatHtml":
|
|
359
|
+
htmlEditorEventBus.emit("format-html");
|
|
360
|
+
break;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
function closeFocusPanel() {
|
|
364
|
+
telemetry.track("User closed focus panel", {
|
|
365
|
+
source: "closeIcon",
|
|
366
|
+
parameters: focusPanelStore.focusedNodeParametersInTelemetryFormat
|
|
367
|
+
});
|
|
368
|
+
focusPanelStore.closeFocusPanel();
|
|
369
|
+
}
|
|
370
|
+
function onExecute() {
|
|
371
|
+
telemetry.track(
|
|
372
|
+
"User executed node from focus panel",
|
|
373
|
+
focusPanelStore.focusedNodeParametersInTelemetryFormat[0]
|
|
374
|
+
);
|
|
375
|
+
}
|
|
376
|
+
const valueChangedDebounced = debounce(valueChanged, { debounceTime: 0 });
|
|
377
|
+
function focusWithDelay() {
|
|
378
|
+
setTimeout(() => {
|
|
379
|
+
void setFocus();
|
|
380
|
+
}, 50);
|
|
381
|
+
}
|
|
382
|
+
function handleKeydown(event) {
|
|
383
|
+
if (event.key === "s" && deviceSupport.isCtrlKeyPressed(event)) {
|
|
384
|
+
event.stopPropagation();
|
|
385
|
+
event.preventDefault();
|
|
386
|
+
if (isReadOnly.value) return;
|
|
387
|
+
emit("saveKeyboardShortcut", event);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
const registerKeyboardListener = () => {
|
|
391
|
+
document.addEventListener("keydown", handleKeydown, true);
|
|
392
|
+
};
|
|
393
|
+
const unregisterKeyboardListener = () => {
|
|
394
|
+
document.removeEventListener("keydown", handleKeydown, true);
|
|
395
|
+
};
|
|
396
|
+
watch(
|
|
397
|
+
[() => focusPanelStore.lastFocusTimestamp, () => expressionModeEnabled.value],
|
|
398
|
+
() => focusWithDelay()
|
|
399
|
+
);
|
|
400
|
+
watch(
|
|
401
|
+
() => focusPanelStore.focusPanelActive,
|
|
402
|
+
(newValue) => {
|
|
403
|
+
if (newValue) {
|
|
404
|
+
registerKeyboardListener();
|
|
405
|
+
} else {
|
|
406
|
+
unregisterKeyboardListener();
|
|
407
|
+
}
|
|
408
|
+
},
|
|
409
|
+
{ immediate: true }
|
|
410
|
+
);
|
|
411
|
+
function onResize(event) {
|
|
412
|
+
focusPanelStore.updateWidth(event.width);
|
|
413
|
+
}
|
|
414
|
+
const onResizeThrottle = useThrottleFn(onResize, 10);
|
|
415
|
+
return (_ctx, _cache) => {
|
|
416
|
+
const _component_NodeExecuteButton = _sfc_main$b;
|
|
417
|
+
const _component_N8nIcon = N8nIcon;
|
|
418
|
+
const _component_ParameterOptions = __unplugin_components_2;
|
|
419
|
+
const _component_ExpressionEditorModalInput = __unplugin_components_3;
|
|
420
|
+
const _component_CodeNodeEditor = __unplugin_components_4;
|
|
421
|
+
const _component_HtmlEditor = __unplugin_components_5;
|
|
422
|
+
const _component_CssEditor = __unplugin_components_6;
|
|
423
|
+
const _component_SqlEditor = __unplugin_components_7;
|
|
424
|
+
const _component_JsEditor = __unplugin_components_8;
|
|
425
|
+
const _component_JsonEditor = __unplugin_components_9;
|
|
426
|
+
const _component_N8nRadioButtons = N8nRadioButtons;
|
|
427
|
+
return focusPanelActive.value ? (openBlock(), createElementBlock("div", {
|
|
428
|
+
key: 0,
|
|
429
|
+
class: normalizeClass(_ctx.$style.wrapper),
|
|
430
|
+
onKeydown: _cache[1] || (_cache[1] = withModifiers(() => {
|
|
431
|
+
}, ["stop"]))
|
|
432
|
+
}, [
|
|
433
|
+
createVNode(unref(N8nResizeWrapper), {
|
|
434
|
+
width: focusPanelWidth.value,
|
|
435
|
+
"supported-directions": ["left"],
|
|
436
|
+
"min-width": 300,
|
|
437
|
+
"max-width": 1e3,
|
|
438
|
+
"grid-size": 8,
|
|
439
|
+
style: normalizeStyle({ width: `${focusPanelWidth.value}px`, zIndex: unref(styles).APP_Z_INDEXES.FOCUS_PANEL }),
|
|
440
|
+
onResize: unref(onResizeThrottle)
|
|
441
|
+
}, {
|
|
442
|
+
default: withCtx(() => [
|
|
443
|
+
createBaseVNode("div", {
|
|
444
|
+
class: normalizeClass(_ctx.$style.container)
|
|
445
|
+
}, [
|
|
446
|
+
resolvedParameter.value ? (openBlock(), createElementBlock("div", {
|
|
447
|
+
key: 0,
|
|
448
|
+
class: normalizeClass(_ctx.$style.content)
|
|
449
|
+
}, [
|
|
450
|
+
createBaseVNode("div", {
|
|
451
|
+
class: normalizeClass(_ctx.$style.tabHeader)
|
|
452
|
+
}, [
|
|
453
|
+
createBaseVNode("div", {
|
|
454
|
+
class: normalizeClass(_ctx.$style.tabHeaderText)
|
|
455
|
+
}, [
|
|
456
|
+
createVNode(unref(N8nText), {
|
|
457
|
+
color: "text-dark",
|
|
458
|
+
size: "small"
|
|
459
|
+
}, {
|
|
460
|
+
default: withCtx(() => [
|
|
461
|
+
createTextVNode(toDisplayString(resolvedParameter.value.parameter.displayName), 1)
|
|
462
|
+
]),
|
|
463
|
+
_: 1
|
|
464
|
+
}),
|
|
465
|
+
createVNode(unref(N8nText), {
|
|
466
|
+
color: "text-base",
|
|
467
|
+
size: "xsmall"
|
|
468
|
+
}, {
|
|
469
|
+
default: withCtx(() => [
|
|
470
|
+
createTextVNode(toDisplayString(resolvedParameter.value.node.name), 1)
|
|
471
|
+
]),
|
|
472
|
+
_: 1
|
|
473
|
+
})
|
|
474
|
+
], 2),
|
|
475
|
+
createBaseVNode("div", {
|
|
476
|
+
class: normalizeClass(_ctx.$style.buttonWrapper)
|
|
477
|
+
}, [
|
|
478
|
+
createVNode(_component_NodeExecuteButton, {
|
|
479
|
+
"data-test-id": "node-execute-button",
|
|
480
|
+
"node-name": resolvedParameter.value.node.name,
|
|
481
|
+
tooltip: `Execute ${resolvedParameter.value.node.name}`,
|
|
482
|
+
disabled: !isExecutable.value,
|
|
483
|
+
size: "small",
|
|
484
|
+
icon: "play",
|
|
485
|
+
square: true,
|
|
486
|
+
"hide-label": true,
|
|
487
|
+
"telemetry-source": "focus",
|
|
488
|
+
onExecute
|
|
489
|
+
}, null, 8, ["node-name", "tooltip", "disabled"]),
|
|
490
|
+
createVNode(_component_N8nIcon, {
|
|
491
|
+
class: normalizeClass(_ctx.$style.closeButton),
|
|
492
|
+
icon: "x",
|
|
493
|
+
color: "text-base",
|
|
494
|
+
size: "xlarge",
|
|
495
|
+
onClick: closeFocusPanel
|
|
496
|
+
}, null, 8, ["class"])
|
|
497
|
+
], 2)
|
|
498
|
+
], 2),
|
|
499
|
+
createBaseVNode("div", {
|
|
500
|
+
class: normalizeClass(_ctx.$style.parameterDetailsWrapper)
|
|
501
|
+
}, [
|
|
502
|
+
createBaseVNode("div", {
|
|
503
|
+
class: normalizeClass(_ctx.$style.parameterOptionsWrapper)
|
|
504
|
+
}, [
|
|
505
|
+
createBaseVNode("div", {
|
|
506
|
+
class: normalizeClass(_ctx.$style.noExecutionDataTip)
|
|
507
|
+
}, [
|
|
508
|
+
!hasNodeRun.value && !isNodeExecuting.value ? (openBlock(), createBlock(unref(InfoTip), {
|
|
509
|
+
key: 0,
|
|
510
|
+
class: normalizeClass(_ctx.$style.delayedShow),
|
|
511
|
+
bold: true
|
|
512
|
+
}, {
|
|
513
|
+
default: withCtx(() => [
|
|
514
|
+
createTextVNode(toDisplayString(unref(locale).baseText("nodeView.focusPanel.noExecutionData")), 1)
|
|
515
|
+
]),
|
|
516
|
+
_: 1
|
|
517
|
+
}, 8, ["class"])) : createCommentVNode("", true)
|
|
518
|
+
], 2),
|
|
519
|
+
isDisplayed.value ? (openBlock(), createBlock(_component_ParameterOptions, {
|
|
520
|
+
key: 0,
|
|
521
|
+
parameter: resolvedParameter.value.parameter,
|
|
522
|
+
value: resolvedParameter.value.value,
|
|
523
|
+
"is-read-only": isReadOnly.value,
|
|
524
|
+
"onUpdate:modelValue": optionSelected
|
|
525
|
+
}, null, 8, ["parameter", "value", "is-read-only"])) : createCommentVNode("", true)
|
|
526
|
+
], 2),
|
|
527
|
+
typeof resolvedParameter.value.value === "string" ? (openBlock(), createElementBlock("div", {
|
|
528
|
+
key: 0,
|
|
529
|
+
class: normalizeClass(_ctx.$style.editorContainer)
|
|
530
|
+
}, [
|
|
531
|
+
!isDisplayed.value ? (openBlock(), createElementBlock("div", {
|
|
532
|
+
key: 0,
|
|
533
|
+
class: normalizeClass([_ctx.$style.content, _ctx.$style.emptyContent])
|
|
534
|
+
}, [
|
|
535
|
+
createBaseVNode("div", {
|
|
536
|
+
class: normalizeClass(_ctx.$style.emptyText)
|
|
537
|
+
}, [
|
|
538
|
+
createVNode(unref(N8nText), { color: "text-base" }, {
|
|
539
|
+
default: withCtx(() => [
|
|
540
|
+
createTextVNode(toDisplayString(unref(locale).baseText("nodeView.focusPanel.missingParameter")), 1)
|
|
541
|
+
]),
|
|
542
|
+
_: 1
|
|
543
|
+
})
|
|
544
|
+
], 2)
|
|
545
|
+
], 2)) : expressionModeEnabled.value ? (openBlock(), createBlock(_component_ExpressionEditorModalInput, {
|
|
546
|
+
key: 1,
|
|
547
|
+
ref_key: "inputField",
|
|
548
|
+
ref: inputField,
|
|
549
|
+
"model-value": resolvedParameter.value.value,
|
|
550
|
+
class: normalizeClass(_ctx.$style.editor),
|
|
551
|
+
"is-read-only": isReadOnly.value,
|
|
552
|
+
path: resolvedParameter.value.parameterPath,
|
|
553
|
+
"data-test-id": "expression-modal-input",
|
|
554
|
+
"target-node-parameter-context": targetNodeParameterContext.value,
|
|
555
|
+
onChange: _cache[0] || (_cache[0] = ($event) => unref(valueChangedDebounced)($event.value))
|
|
556
|
+
}, null, 8, ["model-value", "class", "is-read-only", "path", "target-node-parameter-context"])) : ["json", "string"].includes(resolvedParameter.value.parameter.type) ? (openBlock(), createElementBlock(Fragment, { key: 2 }, [
|
|
557
|
+
editorType.value === "codeNodeEditor" ? (openBlock(), createBlock(_component_CodeNodeEditor, {
|
|
558
|
+
key: 0,
|
|
559
|
+
id: resolvedParameter.value.parameterPath,
|
|
560
|
+
ref_key: "inputField",
|
|
561
|
+
ref: inputField,
|
|
562
|
+
class: normalizeClass(_ctx.$style.heightFull),
|
|
563
|
+
mode: codeEditorMode.value,
|
|
564
|
+
"model-value": resolvedParameter.value.value,
|
|
565
|
+
"default-value": resolvedParameter.value.parameter.default,
|
|
566
|
+
language: editorLanguage.value,
|
|
567
|
+
"is-read-only": isReadOnly.value,
|
|
568
|
+
"target-node-parameter-context": targetNodeParameterContext.value,
|
|
569
|
+
"fill-parent": "",
|
|
570
|
+
"disable-ask-ai": true,
|
|
571
|
+
"onUpdate:modelValue": unref(valueChangedDebounced)
|
|
572
|
+
}, null, 8, ["id", "class", "mode", "model-value", "default-value", "language", "is-read-only", "target-node-parameter-context", "onUpdate:modelValue"])) : editorType.value === "htmlEditor" ? (openBlock(), createBlock(_component_HtmlEditor, {
|
|
573
|
+
key: 1,
|
|
574
|
+
ref_key: "inputField",
|
|
575
|
+
ref: inputField,
|
|
576
|
+
"model-value": resolvedParameter.value.value,
|
|
577
|
+
"is-read-only": isReadOnly.value,
|
|
578
|
+
rows: editorRows.value,
|
|
579
|
+
"disable-expression-coloring": !isHtmlNode.value,
|
|
580
|
+
"disable-expression-completions": !isHtmlNode.value,
|
|
581
|
+
fullscreen: "",
|
|
582
|
+
"target-node-parameter-context": targetNodeParameterContext.value,
|
|
583
|
+
"onUpdate:modelValue": unref(valueChangedDebounced)
|
|
584
|
+
}, null, 8, ["model-value", "is-read-only", "rows", "disable-expression-coloring", "disable-expression-completions", "target-node-parameter-context", "onUpdate:modelValue"])) : editorType.value === "cssEditor" ? (openBlock(), createBlock(_component_CssEditor, {
|
|
585
|
+
key: 2,
|
|
586
|
+
ref_key: "inputField",
|
|
587
|
+
ref: inputField,
|
|
588
|
+
"model-value": resolvedParameter.value.value,
|
|
589
|
+
"is-read-only": isReadOnly.value,
|
|
590
|
+
rows: editorRows.value,
|
|
591
|
+
fullscreen: "",
|
|
592
|
+
"target-node-parameter-context": targetNodeParameterContext.value,
|
|
593
|
+
"onUpdate:modelValue": unref(valueChangedDebounced)
|
|
594
|
+
}, null, 8, ["model-value", "is-read-only", "rows", "target-node-parameter-context", "onUpdate:modelValue"])) : editorType.value === "sqlEditor" ? (openBlock(), createBlock(_component_SqlEditor, {
|
|
595
|
+
key: 3,
|
|
596
|
+
ref_key: "inputField",
|
|
597
|
+
ref: inputField,
|
|
598
|
+
"model-value": resolvedParameter.value.value,
|
|
599
|
+
dialect: getTypeOption("sqlDialect"),
|
|
600
|
+
"is-read-only": isReadOnly.value,
|
|
601
|
+
rows: editorRows.value,
|
|
602
|
+
fullscreen: "",
|
|
603
|
+
"target-node-parameter-context": targetNodeParameterContext.value,
|
|
604
|
+
"onUpdate:modelValue": unref(valueChangedDebounced)
|
|
605
|
+
}, null, 8, ["model-value", "dialect", "is-read-only", "rows", "target-node-parameter-context", "onUpdate:modelValue"])) : editorType.value === "jsEditor" ? (openBlock(), createBlock(_component_JsEditor, {
|
|
606
|
+
key: 4,
|
|
607
|
+
ref_key: "inputField",
|
|
608
|
+
ref: inputField,
|
|
609
|
+
"model-value": resolvedParameter.value.value,
|
|
610
|
+
"is-read-only": isReadOnly.value,
|
|
611
|
+
rows: editorRows.value,
|
|
612
|
+
"posthog-capture": shouldCaptureForPosthog.value,
|
|
613
|
+
"fill-parent": "",
|
|
614
|
+
"onUpdate:modelValue": unref(valueChangedDebounced)
|
|
615
|
+
}, null, 8, ["model-value", "is-read-only", "rows", "posthog-capture", "onUpdate:modelValue"])) : resolvedParameter.value.parameter.type === "json" ? (openBlock(), createBlock(_component_JsonEditor, {
|
|
616
|
+
key: 5,
|
|
617
|
+
ref_key: "inputField",
|
|
618
|
+
ref: inputField,
|
|
619
|
+
"model-value": resolvedParameter.value.value,
|
|
620
|
+
"is-read-only": isReadOnly.value,
|
|
621
|
+
rows: editorRows.value,
|
|
622
|
+
fullscreen: "",
|
|
623
|
+
"fill-parent": "",
|
|
624
|
+
"onUpdate:modelValue": unref(valueChangedDebounced)
|
|
625
|
+
}, null, 8, ["model-value", "is-read-only", "rows", "onUpdate:modelValue"])) : (openBlock(), createBlock(unref(N8nInput), {
|
|
626
|
+
key: 6,
|
|
627
|
+
ref_key: "inputField",
|
|
628
|
+
ref: inputField,
|
|
629
|
+
"model-value": resolvedParameter.value.value,
|
|
630
|
+
class: normalizeClass(_ctx.$style.editor),
|
|
631
|
+
readonly: isReadOnly.value,
|
|
632
|
+
type: "textarea",
|
|
633
|
+
resize: "none",
|
|
634
|
+
"onUpdate:modelValue": unref(valueChangedDebounced)
|
|
635
|
+
}, null, 8, ["model-value", "class", "readonly", "onUpdate:modelValue"]))
|
|
636
|
+
], 64)) : createCommentVNode("", true)
|
|
637
|
+
], 2)) : createCommentVNode("", true)
|
|
638
|
+
], 2)
|
|
639
|
+
], 2)) : (openBlock(), createElementBlock("div", {
|
|
640
|
+
key: 1,
|
|
641
|
+
class: normalizeClass([_ctx.$style.content, _ctx.$style.emptyContent])
|
|
642
|
+
}, [
|
|
643
|
+
createBaseVNode("div", {
|
|
644
|
+
class: normalizeClass(_ctx.$style.emptyText)
|
|
645
|
+
}, [
|
|
646
|
+
createBaseVNode("div", {
|
|
647
|
+
class: normalizeClass(_ctx.$style.focusParameterWrapper)
|
|
648
|
+
}, [
|
|
649
|
+
createBaseVNode("div", {
|
|
650
|
+
class: normalizeClass(_ctx.$style.iconWrapper)
|
|
651
|
+
}, [
|
|
652
|
+
createVNode(_component_N8nIcon, {
|
|
653
|
+
class: normalizeClass(_ctx.$style.forceHover),
|
|
654
|
+
icon: "panel-right",
|
|
655
|
+
size: "medium"
|
|
656
|
+
}, null, 8, ["class"]),
|
|
657
|
+
createVNode(_component_N8nIcon, {
|
|
658
|
+
class: normalizeClass(_ctx.$style.pointerIcon),
|
|
659
|
+
icon: "mouse-pointer",
|
|
660
|
+
color: "text-dark",
|
|
661
|
+
size: "large"
|
|
662
|
+
}, null, 8, ["class"])
|
|
663
|
+
], 2),
|
|
664
|
+
createVNode(_component_N8nIcon, {
|
|
665
|
+
icon: "ellipsis-vertical",
|
|
666
|
+
size: "small",
|
|
667
|
+
color: "text-base"
|
|
668
|
+
}),
|
|
669
|
+
createVNode(_component_N8nRadioButtons, {
|
|
670
|
+
size: "small",
|
|
671
|
+
"model-value": "expression",
|
|
672
|
+
disabled: true,
|
|
673
|
+
options: [
|
|
674
|
+
{ label: unref(locale).baseText("parameterInput.fixed"), value: "fixed" },
|
|
675
|
+
{ label: unref(locale).baseText("parameterInput.expression"), value: "expression" }
|
|
676
|
+
]
|
|
677
|
+
}, null, 8, ["options"])
|
|
678
|
+
], 2),
|
|
679
|
+
createVNode(unref(N8nText), {
|
|
680
|
+
color: "text-base",
|
|
681
|
+
size: "medium",
|
|
682
|
+
bold: true
|
|
683
|
+
}, {
|
|
684
|
+
default: withCtx(() => [
|
|
685
|
+
createTextVNode(toDisplayString(unref(locale).baseText("nodeView.focusPanel.noParameters.title")), 1)
|
|
686
|
+
]),
|
|
687
|
+
_: 1
|
|
688
|
+
}),
|
|
689
|
+
createVNode(unref(N8nText), {
|
|
690
|
+
color: "text-base",
|
|
691
|
+
size: "small"
|
|
692
|
+
}, {
|
|
693
|
+
default: withCtx(() => [
|
|
694
|
+
createTextVNode(toDisplayString(unref(locale).baseText("nodeView.focusPanel.noParameters.subtitle")), 1)
|
|
695
|
+
]),
|
|
696
|
+
_: 1
|
|
697
|
+
})
|
|
698
|
+
], 2)
|
|
699
|
+
], 2))
|
|
700
|
+
], 2)
|
|
701
|
+
]),
|
|
702
|
+
_: 1
|
|
703
|
+
}, 8, ["width", "style", "onResize"])
|
|
704
|
+
], 34)) : createCommentVNode("", true);
|
|
705
|
+
};
|
|
706
|
+
}
|
|
707
|
+
});
|
|
708
|
+
const wrapper$1 = "_wrapper_1ebmp_123";
|
|
709
|
+
const container = "_container_1ebmp_132";
|
|
710
|
+
const content = "_content_1ebmp_138";
|
|
711
|
+
const emptyContent = "_emptyContent_1ebmp_144";
|
|
712
|
+
const emptyText = "_emptyText_1ebmp_149";
|
|
713
|
+
const focusParameterWrapper = "_focusParameterWrapper_1ebmp_155";
|
|
714
|
+
const iconWrapper = "_iconWrapper_1ebmp_162";
|
|
715
|
+
const pointerIcon = "_pointerIcon_1ebmp_166";
|
|
716
|
+
const tabHeader = "_tabHeader_1ebmp_176";
|
|
717
|
+
const tabHeaderText = "_tabHeaderText_1ebmp_183";
|
|
718
|
+
const buttonWrapper = "_buttonWrapper_1ebmp_188";
|
|
719
|
+
const parameterDetailsWrapper = "_parameterDetailsWrapper_1ebmp_193";
|
|
720
|
+
const parameterOptionsWrapper = "_parameterOptionsWrapper_1ebmp_200";
|
|
721
|
+
const noExecutionDataTip = "_noExecutionDataTip_1ebmp_204";
|
|
722
|
+
const editorContainer = "_editorContainer_1ebmp_207";
|
|
723
|
+
const editor = "_editor_1ebmp_207";
|
|
724
|
+
const delayedShow = "_delayedShow_1ebmp_222";
|
|
725
|
+
const triggerShow = "_triggerShow_1ebmp_1";
|
|
726
|
+
const closeButton = "_closeButton_1ebmp_233";
|
|
727
|
+
const heightFull = "_heightFull_1ebmp_237";
|
|
728
|
+
const forceHover = "_forceHover_1ebmp_241";
|
|
729
|
+
const style0$2 = {
|
|
730
|
+
wrapper: wrapper$1,
|
|
731
|
+
container,
|
|
732
|
+
content,
|
|
733
|
+
emptyContent,
|
|
734
|
+
emptyText,
|
|
735
|
+
focusParameterWrapper,
|
|
736
|
+
iconWrapper,
|
|
737
|
+
pointerIcon,
|
|
738
|
+
tabHeader,
|
|
739
|
+
tabHeaderText,
|
|
740
|
+
buttonWrapper,
|
|
741
|
+
parameterDetailsWrapper,
|
|
742
|
+
parameterOptionsWrapper,
|
|
743
|
+
noExecutionDataTip,
|
|
744
|
+
editorContainer,
|
|
745
|
+
editor,
|
|
746
|
+
delayedShow,
|
|
747
|
+
triggerShow,
|
|
748
|
+
closeButton,
|
|
749
|
+
heightFull,
|
|
750
|
+
forceHover
|
|
751
|
+
};
|
|
752
|
+
const cssModules$2 = {
|
|
753
|
+
"$style": style0$2
|
|
754
|
+
};
|
|
755
|
+
const FocusPanel = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["__cssModules", cssModules$2]]);
|
|
756
|
+
const _sfc_main$5 = /* @__PURE__ */ defineComponent({
|
|
757
|
+
__name: "CanvasRunWorkflowButton",
|
|
758
|
+
props: {
|
|
759
|
+
selectedTriggerNodeName: {},
|
|
760
|
+
triggerNodes: {},
|
|
761
|
+
waitingForWebhook: { type: Boolean },
|
|
762
|
+
executing: { type: Boolean },
|
|
763
|
+
disabled: { type: Boolean },
|
|
764
|
+
getNodeType: { type: Function }
|
|
765
|
+
},
|
|
766
|
+
emits: ["mouseenter", "mouseleave", "execute", "selectTriggerNode"],
|
|
767
|
+
setup(__props, { emit: __emit }) {
|
|
768
|
+
const emit = __emit;
|
|
769
|
+
const props = __props;
|
|
770
|
+
const i18n = useI18n();
|
|
771
|
+
const selectableTriggerNodes = computed(
|
|
772
|
+
() => props.triggerNodes.filter((node) => !node.disabled && !isChatNode(node))
|
|
773
|
+
);
|
|
774
|
+
const label = computed(() => {
|
|
775
|
+
if (!props.executing) {
|
|
776
|
+
return i18n.baseText("nodeView.runButtonText.executeWorkflow");
|
|
777
|
+
}
|
|
778
|
+
if (props.waitingForWebhook) {
|
|
779
|
+
return i18n.baseText("nodeView.runButtonText.waitingForTriggerEvent");
|
|
780
|
+
}
|
|
781
|
+
return i18n.baseText("nodeView.runButtonText.executingWorkflow");
|
|
782
|
+
});
|
|
783
|
+
const actions = computed(
|
|
784
|
+
() => props.triggerNodes.filter((node) => !isChatNode(node)).toSorted((a, b) => {
|
|
785
|
+
const [aX, aY] = a.position;
|
|
786
|
+
const [bX, bY] = b.position;
|
|
787
|
+
return aY === bY ? aX - bX : aY - bY;
|
|
788
|
+
}).map((node) => ({
|
|
789
|
+
label: truncateBeforeLast(node.name, 25),
|
|
790
|
+
disabled: !!node.disabled || props.executing,
|
|
791
|
+
id: node.name,
|
|
792
|
+
checked: props.selectedTriggerNodeName === node.name
|
|
793
|
+
}))
|
|
794
|
+
);
|
|
795
|
+
const isSplitButton = computed(
|
|
796
|
+
() => selectableTriggerNodes.value.length > 1 && props.selectedTriggerNodeName !== void 0
|
|
797
|
+
);
|
|
798
|
+
function getNodeTypeByName(name) {
|
|
799
|
+
const node = props.triggerNodes.find((trigger) => trigger.name === name);
|
|
800
|
+
if (!node) {
|
|
801
|
+
return null;
|
|
802
|
+
}
|
|
803
|
+
return props.getNodeType(node.type, node.typeVersion);
|
|
804
|
+
}
|
|
805
|
+
return (_ctx, _cache) => {
|
|
806
|
+
const _component_NodeIcon = NodeIcon;
|
|
807
|
+
return openBlock(), createElementBlock("div", {
|
|
808
|
+
class: normalizeClass([_ctx.$style.component, isSplitButton.value ? _ctx.$style.split : ""])
|
|
809
|
+
}, [
|
|
810
|
+
createVNode(KeyboardShortcutTooltip, {
|
|
811
|
+
label: label.value,
|
|
812
|
+
shortcut: { metaKey: true, keys: ["↵"] },
|
|
813
|
+
disabled: _ctx.executing
|
|
814
|
+
}, {
|
|
815
|
+
default: withCtx(() => [
|
|
816
|
+
createVNode(unref(N8nButton), {
|
|
817
|
+
class: normalizeClass(_ctx.$style.button),
|
|
818
|
+
loading: _ctx.executing,
|
|
819
|
+
disabled: _ctx.disabled,
|
|
820
|
+
size: "large",
|
|
821
|
+
icon: "flask-conical",
|
|
822
|
+
type: "primary",
|
|
823
|
+
"data-test-id": "execute-workflow-button",
|
|
824
|
+
onMouseenter: _cache[0] || (_cache[0] = ($event) => _ctx.$emit("mouseenter", $event)),
|
|
825
|
+
onMouseleave: _cache[1] || (_cache[1] = ($event) => _ctx.$emit("mouseleave", $event)),
|
|
826
|
+
onClick: _cache[2] || (_cache[2] = ($event) => emit("execute"))
|
|
827
|
+
}, {
|
|
828
|
+
default: withCtx(() => [
|
|
829
|
+
createBaseVNode("span", {
|
|
830
|
+
class: normalizeClass(_ctx.$style.buttonContent)
|
|
831
|
+
}, [
|
|
832
|
+
createTextVNode(toDisplayString(label.value) + " ", 1),
|
|
833
|
+
isSplitButton.value ? (openBlock(), createBlock(unref(N8nText), {
|
|
834
|
+
key: 0,
|
|
835
|
+
class: normalizeClass(_ctx.$style.subText),
|
|
836
|
+
bold: false
|
|
837
|
+
}, {
|
|
838
|
+
default: withCtx(() => [
|
|
839
|
+
createVNode(unref(I18nT), {
|
|
840
|
+
keypath: "nodeView.runButtonText.from",
|
|
841
|
+
scope: "global"
|
|
842
|
+
}, {
|
|
843
|
+
nodeName: withCtx(() => [
|
|
844
|
+
createVNode(unref(N8nText), {
|
|
845
|
+
bold: "",
|
|
846
|
+
size: "mini"
|
|
847
|
+
}, {
|
|
848
|
+
default: withCtx(() => [
|
|
849
|
+
createTextVNode(toDisplayString(unref(truncateBeforeLast)(props.selectedTriggerNodeName ?? "", 25)), 1)
|
|
850
|
+
]),
|
|
851
|
+
_: 1
|
|
852
|
+
})
|
|
853
|
+
]),
|
|
854
|
+
_: 1
|
|
855
|
+
})
|
|
856
|
+
]),
|
|
857
|
+
_: 1
|
|
858
|
+
}, 8, ["class"])) : createCommentVNode("", true)
|
|
859
|
+
], 2)
|
|
860
|
+
]),
|
|
861
|
+
_: 1
|
|
862
|
+
}, 8, ["class", "loading", "disabled"])
|
|
863
|
+
]),
|
|
864
|
+
_: 1
|
|
865
|
+
}, 8, ["label", "disabled"]),
|
|
866
|
+
isSplitButton.value ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
|
|
867
|
+
createBaseVNode("div", {
|
|
868
|
+
role: "presentation",
|
|
869
|
+
class: normalizeClass(_ctx.$style.divider)
|
|
870
|
+
}, null, 2),
|
|
871
|
+
createVNode(unref(N8nActionDropdown), {
|
|
872
|
+
class: normalizeClass(_ctx.$style.menu),
|
|
873
|
+
items: actions.value,
|
|
874
|
+
disabled: _ctx.disabled,
|
|
875
|
+
placement: "top",
|
|
876
|
+
onSelect: _cache[3] || (_cache[3] = ($event) => emit("selectTriggerNode", $event))
|
|
877
|
+
}, {
|
|
878
|
+
activator: withCtx(() => [
|
|
879
|
+
createVNode(unref(N8nButton), {
|
|
880
|
+
type: "primary",
|
|
881
|
+
"icon-size": "large",
|
|
882
|
+
disabled: _ctx.disabled,
|
|
883
|
+
class: normalizeClass(_ctx.$style.chevron),
|
|
884
|
+
"aria-label": "Select trigger node",
|
|
885
|
+
icon: "chevron-down"
|
|
886
|
+
}, null, 8, ["disabled", "class"])
|
|
887
|
+
]),
|
|
888
|
+
menuItem: withCtx((item) => [
|
|
889
|
+
createBaseVNode("div", {
|
|
890
|
+
class: normalizeClass([_ctx.$style.menuItem, item.disabled ? _ctx.$style.disabled : ""])
|
|
891
|
+
}, [
|
|
892
|
+
createVNode(_component_NodeIcon, {
|
|
893
|
+
class: normalizeClass(_ctx.$style.menuIcon),
|
|
894
|
+
size: 16,
|
|
895
|
+
"node-type": getNodeTypeByName(item.id)
|
|
896
|
+
}, null, 8, ["class", "node-type"]),
|
|
897
|
+
createBaseVNode("span", null, [
|
|
898
|
+
createVNode(unref(I18nT), {
|
|
899
|
+
keypath: "nodeView.runButtonText.from",
|
|
900
|
+
scope: "global"
|
|
901
|
+
}, {
|
|
902
|
+
nodeName: withCtx(() => [
|
|
903
|
+
createVNode(unref(N8nText), {
|
|
904
|
+
bold: "",
|
|
905
|
+
size: "small"
|
|
906
|
+
}, {
|
|
907
|
+
default: withCtx(() => [
|
|
908
|
+
createTextVNode(toDisplayString(item.label), 1)
|
|
909
|
+
]),
|
|
910
|
+
_: 2
|
|
911
|
+
}, 1024)
|
|
912
|
+
]),
|
|
913
|
+
_: 2
|
|
914
|
+
}, 1024)
|
|
915
|
+
])
|
|
916
|
+
], 2)
|
|
917
|
+
]),
|
|
918
|
+
_: 1
|
|
919
|
+
}, 8, ["class", "items", "disabled"])
|
|
920
|
+
], 64)) : createCommentVNode("", true)
|
|
921
|
+
], 2);
|
|
922
|
+
};
|
|
923
|
+
}
|
|
924
|
+
});
|
|
925
|
+
const component = "_component_p52lz_123";
|
|
926
|
+
const split = "_split_p52lz_129";
|
|
927
|
+
const button = "_button_p52lz_129";
|
|
928
|
+
const divider = "_divider_p52lz_137";
|
|
929
|
+
const chevron = "_chevron_p52lz_142";
|
|
930
|
+
const menu = "_menu_p52lz_148";
|
|
931
|
+
const menuItem = "_menuItem_p52lz_152";
|
|
932
|
+
const disabled = "_disabled_p52lz_158";
|
|
933
|
+
const menuIcon = "_menuIcon_p52lz_158";
|
|
934
|
+
const buttonContent = "_buttonContent_p52lz_162";
|
|
935
|
+
const subText = "_subText_p52lz_169";
|
|
936
|
+
const style0$1 = {
|
|
937
|
+
component,
|
|
938
|
+
split,
|
|
939
|
+
button,
|
|
940
|
+
divider,
|
|
941
|
+
chevron,
|
|
942
|
+
menu,
|
|
943
|
+
menuItem,
|
|
944
|
+
disabled,
|
|
945
|
+
menuIcon,
|
|
946
|
+
buttonContent,
|
|
947
|
+
subText
|
|
948
|
+
};
|
|
949
|
+
const cssModules$1 = {
|
|
950
|
+
"$style": style0$1
|
|
951
|
+
};
|
|
952
|
+
const CanvasRunWorkflowButton = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["__cssModules", cssModules$1]]);
|
|
953
|
+
const state = reactive({
|
|
954
|
+
customActions: {},
|
|
955
|
+
delegatedClickHandler: null
|
|
956
|
+
});
|
|
957
|
+
function useGlobalLinkActions() {
|
|
958
|
+
function registerCustomAction({ key, action }) {
|
|
959
|
+
state.customActions[key] = action;
|
|
960
|
+
}
|
|
961
|
+
function unregisterCustomAction(key) {
|
|
962
|
+
const { [key]: _, ...rest } = state.customActions;
|
|
963
|
+
state.customActions = rest;
|
|
964
|
+
}
|
|
965
|
+
function getElementAttributes(element) {
|
|
966
|
+
const attributesObject = {};
|
|
967
|
+
for (let i = 0; i < element.attributes.length; i++) {
|
|
968
|
+
const attr = element.attributes[i];
|
|
969
|
+
if (attr.name.startsWith("data-action-parameter-")) {
|
|
970
|
+
attributesObject[attr.name.replace("data-action-parameter-", "")] = attr.value;
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
return attributesObject;
|
|
974
|
+
}
|
|
975
|
+
function delegateClick(e) {
|
|
976
|
+
const clickedElement = e.target;
|
|
977
|
+
if (!(clickedElement instanceof Element) || clickedElement.tagName !== "A") return;
|
|
978
|
+
const actionAttribute = clickedElement.getAttribute("data-action");
|
|
979
|
+
if (actionAttribute && typeof availableActions.value[actionAttribute] === "function") {
|
|
980
|
+
e.preventDefault();
|
|
981
|
+
const elementAttributes = getElementAttributes(clickedElement);
|
|
982
|
+
availableActions.value[actionAttribute](elementAttributes);
|
|
983
|
+
}
|
|
984
|
+
}
|
|
985
|
+
function reload() {
|
|
986
|
+
if (window.top) {
|
|
987
|
+
window.top.location.reload();
|
|
988
|
+
} else {
|
|
989
|
+
window.location.reload();
|
|
990
|
+
}
|
|
991
|
+
}
|
|
992
|
+
const availableActions = computed(() => ({
|
|
993
|
+
reload,
|
|
994
|
+
...state.customActions
|
|
995
|
+
}));
|
|
996
|
+
onMounted(() => {
|
|
997
|
+
if (state.delegatedClickHandler) return;
|
|
998
|
+
state.delegatedClickHandler = delegateClick;
|
|
999
|
+
window.addEventListener("click", delegateClick);
|
|
1000
|
+
globalLinkActionsEventBus.on("registerGlobalLinkAction", registerCustomAction);
|
|
1001
|
+
});
|
|
1002
|
+
onUnmounted(() => {
|
|
1003
|
+
window.removeEventListener("click", delegateClick);
|
|
1004
|
+
state.delegatedClickHandler = null;
|
|
1005
|
+
globalLinkActionsEventBus.off("registerGlobalLinkAction", registerCustomAction);
|
|
1006
|
+
});
|
|
1007
|
+
return {
|
|
1008
|
+
registerCustomAction,
|
|
1009
|
+
unregisterCustomAction
|
|
1010
|
+
};
|
|
1011
|
+
}
|
|
1012
|
+
const _sfc_main$4 = /* @__PURE__ */ defineComponent({
|
|
1013
|
+
__name: "CanvasStopCurrentExecutionButton",
|
|
1014
|
+
props: {
|
|
1015
|
+
stopping: { type: Boolean }
|
|
1016
|
+
},
|
|
1017
|
+
setup(__props) {
|
|
1018
|
+
const props = __props;
|
|
1019
|
+
const i18n = useI18n();
|
|
1020
|
+
const title = computed(
|
|
1021
|
+
() => props.stopping ? i18n.baseText("nodeView.stoppingCurrentExecution") : i18n.baseText("nodeView.stopCurrentExecution")
|
|
1022
|
+
);
|
|
1023
|
+
return (_ctx, _cache) => {
|
|
1024
|
+
const _component_N8nIconButton = _sfc_main$a;
|
|
1025
|
+
return openBlock(), createBlock(_component_N8nIconButton, {
|
|
1026
|
+
icon: "square",
|
|
1027
|
+
size: "large",
|
|
1028
|
+
class: "stop-execution",
|
|
1029
|
+
type: "secondary",
|
|
1030
|
+
title: title.value,
|
|
1031
|
+
loading: _ctx.stopping,
|
|
1032
|
+
"data-test-id": "stop-execution-button"
|
|
1033
|
+
}, null, 8, ["title", "loading"]);
|
|
1034
|
+
};
|
|
1035
|
+
}
|
|
1036
|
+
});
|
|
1037
|
+
const _sfc_main$3 = /* @__PURE__ */ defineComponent({
|
|
1038
|
+
__name: "CanvasStopWaitingForWebhookButton",
|
|
1039
|
+
setup(__props) {
|
|
1040
|
+
const i18n = useI18n();
|
|
1041
|
+
return (_ctx, _cache) => {
|
|
1042
|
+
const _component_N8nIconButton = _sfc_main$a;
|
|
1043
|
+
return openBlock(), createBlock(_component_N8nIconButton, {
|
|
1044
|
+
class: "stop-execution",
|
|
1045
|
+
icon: "square",
|
|
1046
|
+
size: "large",
|
|
1047
|
+
title: unref(i18n).baseText("nodeView.stopWaitingForWebhookCall"),
|
|
1048
|
+
type: "secondary",
|
|
1049
|
+
"data-test-id": "stop-execution-waiting-for-webhook-button"
|
|
1050
|
+
}, null, 8, ["title"]);
|
|
1051
|
+
};
|
|
1052
|
+
}
|
|
1053
|
+
});
|
|
1054
|
+
const _hoisted_1 = { "data-action": "reload" };
|
|
1055
|
+
const _hoisted_2 = {
|
|
1056
|
+
href: "https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.wait/",
|
|
1057
|
+
target: "_blank"
|
|
1058
|
+
};
|
|
1059
|
+
const _sfc_main$2 = /* @__PURE__ */ defineComponent({
|
|
1060
|
+
__name: "NodeViewUnfinishedWorkflowMessage",
|
|
1061
|
+
setup(__props) {
|
|
1062
|
+
const i18 = useI18n();
|
|
1063
|
+
return (_ctx, _cache) => {
|
|
1064
|
+
return openBlock(), createElementBlock("div", null, [
|
|
1065
|
+
createBaseVNode("a", _hoisted_1, toDisplayString(unref(i18).baseText("nodeView.refresh")), 1),
|
|
1066
|
+
createTextVNode(" " + toDisplayString(unref(i18).baseText("nodeView.toSeeTheLatestStatus")) + ". ", 1),
|
|
1067
|
+
_cache[0] || (_cache[0] = createBaseVNode("br", null, null, -1)),
|
|
1068
|
+
createBaseVNode("a", _hoisted_2, toDisplayString(unref(i18).baseText("nodeView.moreInfo")), 1)
|
|
1069
|
+
]);
|
|
1070
|
+
};
|
|
1071
|
+
}
|
|
1072
|
+
});
|
|
1073
|
+
const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
1074
|
+
__name: "CanvasChatButton",
|
|
1075
|
+
props: {
|
|
1076
|
+
label: {},
|
|
1077
|
+
type: {}
|
|
1078
|
+
},
|
|
1079
|
+
setup(__props) {
|
|
1080
|
+
return (_ctx, _cache) => {
|
|
1081
|
+
const _component_N8nButton = N8nButton;
|
|
1082
|
+
return openBlock(), createBlock(_component_N8nButton, {
|
|
1083
|
+
label: _ctx.label,
|
|
1084
|
+
size: "large",
|
|
1085
|
+
icon: "message-circle",
|
|
1086
|
+
type: _ctx.type,
|
|
1087
|
+
"data-test-id": "workflow-chat-button"
|
|
1088
|
+
}, null, 8, ["label", "type"]);
|
|
1089
|
+
};
|
|
1090
|
+
}
|
|
1091
|
+
});
|
|
1092
|
+
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
1093
|
+
...{
|
|
1094
|
+
name: "NodeView"
|
|
1095
|
+
},
|
|
1096
|
+
__name: "NodeView",
|
|
1097
|
+
setup(__props) {
|
|
1098
|
+
const LazyNodeCreation = defineAsyncComponent(
|
|
1099
|
+
async () => await __vitePreload(() => import("./NodeCreation-B9FRFHG0.js").then((n) => n.N), true ? __vite__mapDeps([0,1,2,3]) : void 0)
|
|
1100
|
+
);
|
|
1101
|
+
const LazyNodeDetailsView = defineAsyncComponent(
|
|
1102
|
+
async () => await __vitePreload(() => import("./NodeDetailsView-CQQOZQXq.js"), true ? __vite__mapDeps([4,1,2,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]) : void 0)
|
|
1103
|
+
);
|
|
1104
|
+
const LazyNodeDetailsViewV2 = defineAsyncComponent(
|
|
1105
|
+
async () => await __vitePreload(() => import("./NodeDetailsViewV2-DKnduvJH.js"), true ? __vite__mapDeps([20,1,2,5,6,7,8,9,10,11,12,13,14,15,16,17,18,21]) : void 0)
|
|
1106
|
+
);
|
|
1107
|
+
const LazySetupWorkflowCredentialsButton = defineAsyncComponent(
|
|
1108
|
+
async () => await __vitePreload(() => import("./SetupWorkflowCredentialsButton-y92onTNS.js"), true ? __vite__mapDeps([22,1,2]) : void 0)
|
|
1109
|
+
);
|
|
1110
|
+
const $style = useCssModule();
|
|
1111
|
+
const router = useRouter();
|
|
1112
|
+
const route = useRoute();
|
|
1113
|
+
const i18n = useI18n();
|
|
1114
|
+
const telemetry = useTelemetry();
|
|
1115
|
+
const externalHooks = useExternalHooks();
|
|
1116
|
+
const toast = useToast();
|
|
1117
|
+
const message = useMessage();
|
|
1118
|
+
const documentTitle = useDocumentTitle();
|
|
1119
|
+
const workflowHelpers = useWorkflowHelpers();
|
|
1120
|
+
const workflowSaving = useWorkflowSaving({ router });
|
|
1121
|
+
const nodeHelpers = useNodeHelpers();
|
|
1122
|
+
const nodeTypesStore = useNodeTypesStore();
|
|
1123
|
+
const uiStore = useUIStore();
|
|
1124
|
+
const workflowsStore = useWorkflowsStore();
|
|
1125
|
+
const sourceControlStore = useSourceControlStore();
|
|
1126
|
+
const nodeCreatorStore = useNodeCreatorStore();
|
|
1127
|
+
const settingsStore = useSettingsStore();
|
|
1128
|
+
const credentialsStore = useCredentialsStore();
|
|
1129
|
+
const environmentsStore = useEnvironmentsStore();
|
|
1130
|
+
const externalSecretsStore = useExternalSecretsStore();
|
|
1131
|
+
const rootStore = useRootStore();
|
|
1132
|
+
const executionsStore = useExecutionsStore();
|
|
1133
|
+
const canvasStore = useCanvasStore();
|
|
1134
|
+
const npsSurveyStore = useNpsSurveyStore();
|
|
1135
|
+
const historyStore = useHistoryStore();
|
|
1136
|
+
const projectsStore = useProjectsStore();
|
|
1137
|
+
const usersStore = useUsersStore();
|
|
1138
|
+
const tagsStore = useTagsStore();
|
|
1139
|
+
const pushConnectionStore = usePushConnectionStore();
|
|
1140
|
+
const ndvStore = useNDVStore();
|
|
1141
|
+
const focusPanelStore = useFocusPanelStore();
|
|
1142
|
+
const templatesStore = useTemplatesStore();
|
|
1143
|
+
const builderStore = useBuilderStore();
|
|
1144
|
+
const foldersStore = useFoldersStore();
|
|
1145
|
+
const posthogStore = usePostHog();
|
|
1146
|
+
const agentRequestStore = useAgentRequestStore();
|
|
1147
|
+
const logsStore = useLogsStore();
|
|
1148
|
+
const aiTemplatesStarterCollectionStore = useAITemplatesStarterCollectionStore();
|
|
1149
|
+
const { addBeforeUnloadEventBindings, removeBeforeUnloadEventBindings } = useBeforeUnload({
|
|
1150
|
+
route
|
|
1151
|
+
});
|
|
1152
|
+
const { registerCustomAction, unregisterCustomAction } = useGlobalLinkActions();
|
|
1153
|
+
const { runWorkflow, runEntireWorkflow, stopCurrentExecution, stopWaitingForWebhook } = useRunWorkflow({ router });
|
|
1154
|
+
const {
|
|
1155
|
+
updateNodePosition,
|
|
1156
|
+
updateNodesPosition,
|
|
1157
|
+
tidyUp,
|
|
1158
|
+
revertUpdateNodePosition,
|
|
1159
|
+
renameNode,
|
|
1160
|
+
revertRenameNode,
|
|
1161
|
+
revertReplaceNodeParameters,
|
|
1162
|
+
setNodeActive,
|
|
1163
|
+
setNodeSelected,
|
|
1164
|
+
toggleNodesDisabled,
|
|
1165
|
+
revertToggleNodeDisabled,
|
|
1166
|
+
toggleNodesPinned,
|
|
1167
|
+
setNodeParameters,
|
|
1168
|
+
deleteNode,
|
|
1169
|
+
deleteNodes,
|
|
1170
|
+
copyNodes,
|
|
1171
|
+
cutNodes,
|
|
1172
|
+
duplicateNodes,
|
|
1173
|
+
revertDeleteNode,
|
|
1174
|
+
addNodes,
|
|
1175
|
+
importTemplate,
|
|
1176
|
+
revertAddNode,
|
|
1177
|
+
createConnection,
|
|
1178
|
+
revertCreateConnection,
|
|
1179
|
+
deleteConnection,
|
|
1180
|
+
revertDeleteConnection,
|
|
1181
|
+
revalidateNodeInputConnections,
|
|
1182
|
+
revalidateNodeOutputConnections,
|
|
1183
|
+
setNodeActiveByName,
|
|
1184
|
+
clearNodeActive,
|
|
1185
|
+
addConnections,
|
|
1186
|
+
tryToOpenSubworkflowInNewTab,
|
|
1187
|
+
importWorkflowData,
|
|
1188
|
+
fetchWorkflowDataFromUrl,
|
|
1189
|
+
resetWorkspace,
|
|
1190
|
+
initializeWorkspace,
|
|
1191
|
+
openExecution,
|
|
1192
|
+
editableWorkflow,
|
|
1193
|
+
editableWorkflowObject,
|
|
1194
|
+
lastClickPosition,
|
|
1195
|
+
startChat
|
|
1196
|
+
} = useCanvasOperations();
|
|
1197
|
+
const { extractWorkflow } = useWorkflowExtraction();
|
|
1198
|
+
const { applyExecutionData } = useExecutionDebugging();
|
|
1199
|
+
useClipboard({ onPaste: onClipboardPaste });
|
|
1200
|
+
const isLoading = ref(true);
|
|
1201
|
+
const isBlankRedirect = ref(false);
|
|
1202
|
+
const readOnlyNotification = ref(null);
|
|
1203
|
+
const isProductionExecutionPreview = ref(false);
|
|
1204
|
+
const isExecutionPreview = ref(false);
|
|
1205
|
+
const canOpenNDV = ref(true);
|
|
1206
|
+
const hideNodeIssues = ref(false);
|
|
1207
|
+
const fallbackNodes = ref([]);
|
|
1208
|
+
const initializedWorkflowId = ref();
|
|
1209
|
+
const workflowId = computed(() => {
|
|
1210
|
+
const workflowIdParam = route.params.name;
|
|
1211
|
+
return [PLACEHOLDER_EMPTY_WORKFLOW_ID, NEW_WORKFLOW_ID].includes(workflowIdParam) ? void 0 : workflowIdParam;
|
|
1212
|
+
});
|
|
1213
|
+
const routeNodeId = computed(() => route.params.nodeId);
|
|
1214
|
+
const isNewWorkflowRoute = computed(() => route.name === VIEWS.NEW_WORKFLOW || !workflowId.value);
|
|
1215
|
+
const isWorkflowRoute = computed(() => !!route?.meta?.nodeView || isDemoRoute.value);
|
|
1216
|
+
const isDemoRoute = computed(() => route.name === VIEWS.DEMO);
|
|
1217
|
+
const isReadOnlyRoute = computed(() => !!route?.meta?.readOnlyCanvas);
|
|
1218
|
+
const isReadOnlyEnvironment = computed(() => {
|
|
1219
|
+
return sourceControlStore.preferences.branchReadOnly;
|
|
1220
|
+
});
|
|
1221
|
+
const isNDVV2 = computed(
|
|
1222
|
+
() => posthogStore.isVariantEnabled(
|
|
1223
|
+
NDV_UI_OVERHAUL_EXPERIMENT.name,
|
|
1224
|
+
NDV_UI_OVERHAUL_EXPERIMENT.variant
|
|
1225
|
+
)
|
|
1226
|
+
);
|
|
1227
|
+
const isCanvasReadOnly = computed(() => {
|
|
1228
|
+
return isDemoRoute.value || isReadOnlyEnvironment.value || !(workflowPermissions.value.update ?? projectPermissions.value.workflow.update) || editableWorkflow.value.isArchived;
|
|
1229
|
+
});
|
|
1230
|
+
const showFallbackNodes = computed(() => triggerNodes.value.length === 0);
|
|
1231
|
+
const keyBindingsEnabled = computed(() => {
|
|
1232
|
+
return !ndvStore.activeNode && uiStore.activeModals.length === 0;
|
|
1233
|
+
});
|
|
1234
|
+
const isLogsPanelOpen = computed(() => logsStore.isOpen);
|
|
1235
|
+
async function initializeData() {
|
|
1236
|
+
const loadPromises = (() => {
|
|
1237
|
+
if (settingsStore.isPreviewMode && isDemoRoute.value) return [];
|
|
1238
|
+
const promises = [
|
|
1239
|
+
workflowsStore.fetchActiveWorkflows(),
|
|
1240
|
+
credentialsStore.fetchAllCredentials(),
|
|
1241
|
+
credentialsStore.fetchCredentialTypes(true)
|
|
1242
|
+
];
|
|
1243
|
+
if (settingsStore.isEnterpriseFeatureEnabled[EnterpriseEditionFeature.Variables]) {
|
|
1244
|
+
promises.push(environmentsStore.fetchAllVariables());
|
|
1245
|
+
}
|
|
1246
|
+
if (settingsStore.isEnterpriseFeatureEnabled[EnterpriseEditionFeature.ExternalSecrets]) {
|
|
1247
|
+
promises.push(externalSecretsStore.fetchAllSecrets());
|
|
1248
|
+
}
|
|
1249
|
+
return promises;
|
|
1250
|
+
})();
|
|
1251
|
+
if (nodeTypesStore.allNodeTypes.length === 0) {
|
|
1252
|
+
loadPromises.push(nodeTypesStore.getNodeTypes());
|
|
1253
|
+
}
|
|
1254
|
+
try {
|
|
1255
|
+
await Promise.all(loadPromises);
|
|
1256
|
+
} catch (error) {
|
|
1257
|
+
toast.showError(
|
|
1258
|
+
error,
|
|
1259
|
+
i18n.baseText("nodeView.showError.mounted1.title"),
|
|
1260
|
+
i18n.baseText("nodeView.showError.mounted1.message") + ":"
|
|
1261
|
+
);
|
|
1262
|
+
return;
|
|
1263
|
+
}
|
|
1264
|
+
}
|
|
1265
|
+
async function initializeRoute(force = false) {
|
|
1266
|
+
if (route.query.action === "workflowSave") {
|
|
1267
|
+
uiStore.stateIsDirty = false;
|
|
1268
|
+
await router.replace({
|
|
1269
|
+
query: { ...route.query, action: void 0 }
|
|
1270
|
+
});
|
|
1271
|
+
return;
|
|
1272
|
+
}
|
|
1273
|
+
if (route.query.action === "addEvaluationTrigger") {
|
|
1274
|
+
nodeCreatorStore.openNodeCreatorForTriggerNodes(
|
|
1275
|
+
NODE_CREATOR_OPEN_SOURCES.ADD_EVALUATION_TRIGGER_BUTTON
|
|
1276
|
+
);
|
|
1277
|
+
} else if (route.query.action === "addEvaluationNode") {
|
|
1278
|
+
nodeCreatorStore.openNodeCreatorForActions(
|
|
1279
|
+
EVALUATION_NODE_TYPE,
|
|
1280
|
+
NODE_CREATOR_OPEN_SOURCES.ADD_EVALUATION_NODE_BUTTON
|
|
1281
|
+
);
|
|
1282
|
+
} else if (route.query.action === "executeEvaluation") {
|
|
1283
|
+
if (evaluationTriggerNode.value) {
|
|
1284
|
+
void runEntireWorkflow("node", evaluationTriggerNode.value.name);
|
|
1285
|
+
}
|
|
1286
|
+
}
|
|
1287
|
+
const isAlreadyInitialized = !force && initializedWorkflowId.value && [NEW_WORKFLOW_ID, workflowId.value].includes(initializedWorkflowId.value);
|
|
1288
|
+
if (isBlankRedirect.value) {
|
|
1289
|
+
isBlankRedirect.value = false;
|
|
1290
|
+
} else if (route.name === VIEWS.TEMPLATE_IMPORT) {
|
|
1291
|
+
const templateId = route.params.id;
|
|
1292
|
+
const loadWorkflowFromJSON = route.query.fromJson === "true";
|
|
1293
|
+
if (loadWorkflowFromJSON) {
|
|
1294
|
+
const easyAiWorkflowJson = getEasyAiWorkflowJson();
|
|
1295
|
+
const ragStarterWorkflowJson = getRagStarterWorkflowJson();
|
|
1296
|
+
switch (templateId) {
|
|
1297
|
+
case easyAiWorkflowJson.meta.templateId:
|
|
1298
|
+
await openTemplateFromWorkflowJSON(easyAiWorkflowJson);
|
|
1299
|
+
break;
|
|
1300
|
+
case ragStarterWorkflowJson.meta.templateId:
|
|
1301
|
+
await openTemplateFromWorkflowJSON(ragStarterWorkflowJson);
|
|
1302
|
+
break;
|
|
1303
|
+
default:
|
|
1304
|
+
toast.showError(
|
|
1305
|
+
new Error(i18n.baseText("nodeView.couldntLoadWorkflow.invalidWorkflowObject")),
|
|
1306
|
+
i18n.baseText("nodeView.couldntImportWorkflow")
|
|
1307
|
+
);
|
|
1308
|
+
await router.replace({ name: VIEWS.NEW_WORKFLOW });
|
|
1309
|
+
}
|
|
1310
|
+
} else {
|
|
1311
|
+
await openWorkflowTemplate(templateId.toString());
|
|
1312
|
+
}
|
|
1313
|
+
} else if (isWorkflowRoute.value) {
|
|
1314
|
+
if (!isAlreadyInitialized) {
|
|
1315
|
+
historyStore.reset();
|
|
1316
|
+
if (!isDemoRoute.value) {
|
|
1317
|
+
await loadCredentials();
|
|
1318
|
+
}
|
|
1319
|
+
if (isNewWorkflowRoute.value || !workflowId.value) {
|
|
1320
|
+
if (route.meta?.nodeView === true) {
|
|
1321
|
+
await initializeWorkspaceForNewWorkflow();
|
|
1322
|
+
}
|
|
1323
|
+
return;
|
|
1324
|
+
}
|
|
1325
|
+
await initializeWorkspaceForExistingWorkflow(workflowId.value);
|
|
1326
|
+
void nextTick(() => {
|
|
1327
|
+
updateNodesIssues();
|
|
1328
|
+
});
|
|
1329
|
+
}
|
|
1330
|
+
if (route.name === VIEWS.EXECUTION_DEBUG) {
|
|
1331
|
+
await initializeDebugMode();
|
|
1332
|
+
}
|
|
1333
|
+
}
|
|
1334
|
+
}
|
|
1335
|
+
async function initializeWorkspaceForNewWorkflow() {
|
|
1336
|
+
resetWorkspace();
|
|
1337
|
+
const parentFolderId = route.query.parentFolderId;
|
|
1338
|
+
await workflowsStore.getNewWorkflowDataAndMakeShareable(
|
|
1339
|
+
void 0,
|
|
1340
|
+
projectsStore.currentProjectId,
|
|
1341
|
+
parentFolderId
|
|
1342
|
+
);
|
|
1343
|
+
if (projectsStore.currentProjectId) {
|
|
1344
|
+
await fetchAndSetProject(projectsStore.currentProjectId);
|
|
1345
|
+
}
|
|
1346
|
+
await fetchAndSetParentFolder(parentFolderId);
|
|
1347
|
+
uiStore.nodeViewInitialized = true;
|
|
1348
|
+
initializedWorkflowId.value = NEW_WORKFLOW_ID;
|
|
1349
|
+
}
|
|
1350
|
+
async function fetchAndSetParentFolder(folderId) {
|
|
1351
|
+
if (folderId) {
|
|
1352
|
+
let parentFolder = foldersStore.getCachedFolder(folderId);
|
|
1353
|
+
if (!parentFolder && projectsStore.currentProjectId) {
|
|
1354
|
+
await foldersStore.getFolderPath(projectsStore.currentProjectId, folderId);
|
|
1355
|
+
parentFolder = foldersStore.getCachedFolder(folderId);
|
|
1356
|
+
}
|
|
1357
|
+
if (parentFolder) {
|
|
1358
|
+
workflowsStore.setParentFolder({
|
|
1359
|
+
...parentFolder,
|
|
1360
|
+
parentFolderId: parentFolder.parentFolder ?? null
|
|
1361
|
+
});
|
|
1362
|
+
}
|
|
1363
|
+
}
|
|
1364
|
+
}
|
|
1365
|
+
async function fetchAndSetProject(projectId) {
|
|
1366
|
+
if (!projectsStore.currentProject) {
|
|
1367
|
+
const project = await projectsStore.fetchProject(projectId);
|
|
1368
|
+
projectsStore.setCurrentProject(project);
|
|
1369
|
+
}
|
|
1370
|
+
}
|
|
1371
|
+
async function initializeWorkspaceForExistingWorkflow(id) {
|
|
1372
|
+
try {
|
|
1373
|
+
const workflowData = await workflowsStore.fetchWorkflow(id);
|
|
1374
|
+
openWorkflow(workflowData);
|
|
1375
|
+
if (workflowData.parentFolder) {
|
|
1376
|
+
workflowsStore.setParentFolder(workflowData.parentFolder);
|
|
1377
|
+
}
|
|
1378
|
+
if (workflowData.meta?.onboardingId) {
|
|
1379
|
+
trackOpenWorkflowFromOnboardingTemplate();
|
|
1380
|
+
}
|
|
1381
|
+
if (workflowData.meta?.templateId?.startsWith("035_template_onboarding")) {
|
|
1382
|
+
aiTemplatesStarterCollectionStore.trackUserOpenedWorkflow(
|
|
1383
|
+
workflowData.meta.templateId.split("-").pop() ?? ""
|
|
1384
|
+
);
|
|
1385
|
+
}
|
|
1386
|
+
await projectsStore.setProjectNavActiveIdByWorkflowHomeProject(workflowData.homeProject);
|
|
1387
|
+
} catch (error) {
|
|
1388
|
+
if (error.httpStatusCode === 404) {
|
|
1389
|
+
return await router.replace({
|
|
1390
|
+
name: VIEWS.ENTITY_NOT_FOUND,
|
|
1391
|
+
params: { entityType: "workflow" }
|
|
1392
|
+
});
|
|
1393
|
+
}
|
|
1394
|
+
if (error.httpStatusCode === 403) {
|
|
1395
|
+
return await router.replace({
|
|
1396
|
+
name: VIEWS.ENTITY_UNAUTHORIZED,
|
|
1397
|
+
params: { entityType: "workflow" }
|
|
1398
|
+
});
|
|
1399
|
+
}
|
|
1400
|
+
toast.showError(error, i18n.baseText("openWorkflow.workflowNotFoundError"));
|
|
1401
|
+
void router.push({
|
|
1402
|
+
name: VIEWS.NEW_WORKFLOW
|
|
1403
|
+
});
|
|
1404
|
+
} finally {
|
|
1405
|
+
uiStore.nodeViewInitialized = true;
|
|
1406
|
+
initializedWorkflowId.value = workflowId.value;
|
|
1407
|
+
}
|
|
1408
|
+
}
|
|
1409
|
+
function updateNodesIssues() {
|
|
1410
|
+
nodeHelpers.updateNodesInputIssues();
|
|
1411
|
+
nodeHelpers.updateNodesCredentialsIssues();
|
|
1412
|
+
nodeHelpers.updateNodesParameterIssues();
|
|
1413
|
+
}
|
|
1414
|
+
function openWorkflow(data) {
|
|
1415
|
+
resetWorkspace();
|
|
1416
|
+
workflowHelpers.setDocumentTitle(data.name, "IDLE");
|
|
1417
|
+
initializeWorkspace(data);
|
|
1418
|
+
void externalHooks.run("workflow.open", {
|
|
1419
|
+
workflowId: data.id,
|
|
1420
|
+
workflowName: data.name
|
|
1421
|
+
});
|
|
1422
|
+
fitView();
|
|
1423
|
+
}
|
|
1424
|
+
function trackOpenWorkflowFromOnboardingTemplate() {
|
|
1425
|
+
telemetry.track(
|
|
1426
|
+
`User opened workflow from onboarding template with ID ${editableWorkflow.value.meta?.onboardingId}`,
|
|
1427
|
+
{
|
|
1428
|
+
workflow_id: workflowId.value
|
|
1429
|
+
}
|
|
1430
|
+
);
|
|
1431
|
+
}
|
|
1432
|
+
async function openTemplateFromWorkflowJSON(workflow) {
|
|
1433
|
+
if (!workflow.nodes || !workflow.connections) {
|
|
1434
|
+
toast.showError(
|
|
1435
|
+
new Error(i18n.baseText("nodeView.couldntLoadWorkflow.invalidWorkflowObject")),
|
|
1436
|
+
i18n.baseText("nodeView.couldntImportWorkflow")
|
|
1437
|
+
);
|
|
1438
|
+
await router.replace({ name: VIEWS.NEW_WORKFLOW });
|
|
1439
|
+
return;
|
|
1440
|
+
}
|
|
1441
|
+
resetWorkspace();
|
|
1442
|
+
canvasStore.startLoading();
|
|
1443
|
+
canvasStore.setLoadingText(i18n.baseText("nodeView.loadingTemplate"));
|
|
1444
|
+
workflowsStore.currentWorkflowExecutions = [];
|
|
1445
|
+
executionsStore.activeExecution = null;
|
|
1446
|
+
isBlankRedirect.value = true;
|
|
1447
|
+
const templateId = workflow.meta.templateId;
|
|
1448
|
+
const parentFolderId = route.query.parentFolderId;
|
|
1449
|
+
await router.replace({
|
|
1450
|
+
name: VIEWS.NEW_WORKFLOW,
|
|
1451
|
+
query: { templateId, parentFolderId }
|
|
1452
|
+
});
|
|
1453
|
+
await importTemplate({ id: templateId, name: workflow.name, workflow });
|
|
1454
|
+
uiStore.stateIsDirty = true;
|
|
1455
|
+
canvasStore.stopLoading();
|
|
1456
|
+
fitView();
|
|
1457
|
+
}
|
|
1458
|
+
async function openWorkflowTemplate(templateId) {
|
|
1459
|
+
resetWorkspace();
|
|
1460
|
+
canvasStore.startLoading();
|
|
1461
|
+
canvasStore.setLoadingText(i18n.baseText("nodeView.loadingTemplate"));
|
|
1462
|
+
workflowsStore.currentWorkflowExecutions = [];
|
|
1463
|
+
executionsStore.activeExecution = null;
|
|
1464
|
+
let data;
|
|
1465
|
+
try {
|
|
1466
|
+
void externalHooks.run("template.requested", { templateId });
|
|
1467
|
+
data = await templatesStore.getFixedWorkflowTemplate(templateId);
|
|
1468
|
+
if (!data) {
|
|
1469
|
+
throw new Error(
|
|
1470
|
+
i18n.baseText("nodeView.workflowTemplateWithIdCouldNotBeFound", {
|
|
1471
|
+
interpolate: { templateId }
|
|
1472
|
+
})
|
|
1473
|
+
);
|
|
1474
|
+
}
|
|
1475
|
+
} catch (error) {
|
|
1476
|
+
toast.showError(error, i18n.baseText("nodeView.couldntImportWorkflow"));
|
|
1477
|
+
await router.replace({ name: VIEWS.NEW_WORKFLOW });
|
|
1478
|
+
return;
|
|
1479
|
+
}
|
|
1480
|
+
trackOpenWorkflowTemplate(templateId);
|
|
1481
|
+
isBlankRedirect.value = true;
|
|
1482
|
+
await router.replace({ name: VIEWS.NEW_WORKFLOW, query: { templateId } });
|
|
1483
|
+
await importTemplate({ id: templateId, name: data.name, workflow: data.workflow });
|
|
1484
|
+
uiStore.stateIsDirty = true;
|
|
1485
|
+
canvasStore.stopLoading();
|
|
1486
|
+
void externalHooks.run("template.open", {
|
|
1487
|
+
templateId,
|
|
1488
|
+
templateName: data.name,
|
|
1489
|
+
workflow: data.workflow
|
|
1490
|
+
});
|
|
1491
|
+
fitView();
|
|
1492
|
+
}
|
|
1493
|
+
function trackOpenWorkflowTemplate(templateId) {
|
|
1494
|
+
telemetry.track("User inserted workflow template", {
|
|
1495
|
+
source: "workflow",
|
|
1496
|
+
template_id: tryToParseNumber(templateId),
|
|
1497
|
+
wf_template_repo_session_id: templatesStore.previousSessionId
|
|
1498
|
+
});
|
|
1499
|
+
}
|
|
1500
|
+
const triggerNodes = computed(() => {
|
|
1501
|
+
return editableWorkflow.value.nodes.filter(
|
|
1502
|
+
(node) => node.type === START_NODE_TYPE || nodeTypesStore.isTriggerNode(node.type)
|
|
1503
|
+
);
|
|
1504
|
+
});
|
|
1505
|
+
const containsTriggerNodes = computed(() => triggerNodes.value.length > 0);
|
|
1506
|
+
const allTriggerNodesDisabled = computed(() => {
|
|
1507
|
+
const disabledTriggerNodes = triggerNodes.value.filter((node) => node.disabled);
|
|
1508
|
+
return disabledTriggerNodes.length === triggerNodes.value.length;
|
|
1509
|
+
});
|
|
1510
|
+
function onTidyUp(event) {
|
|
1511
|
+
tidyUp(event);
|
|
1512
|
+
}
|
|
1513
|
+
function onExtractWorkflow(nodeIds) {
|
|
1514
|
+
void extractWorkflow(nodeIds);
|
|
1515
|
+
}
|
|
1516
|
+
function onUpdateNodesPosition(events) {
|
|
1517
|
+
updateNodesPosition(events, { trackHistory: true });
|
|
1518
|
+
}
|
|
1519
|
+
function onUpdateNodePosition(id, position) {
|
|
1520
|
+
updateNodePosition(id, position, { trackHistory: true });
|
|
1521
|
+
}
|
|
1522
|
+
function onRevertNodePosition({ nodeName, position }) {
|
|
1523
|
+
revertUpdateNodePosition(nodeName, { x: position[0], y: position[1] });
|
|
1524
|
+
}
|
|
1525
|
+
function onDeleteNode(id) {
|
|
1526
|
+
const matchedFallbackNode = fallbackNodes.value.findIndex((node) => node.id === id);
|
|
1527
|
+
if (matchedFallbackNode >= 0) {
|
|
1528
|
+
fallbackNodes.value.splice(matchedFallbackNode, 1);
|
|
1529
|
+
} else {
|
|
1530
|
+
deleteNode(id, { trackHistory: true });
|
|
1531
|
+
}
|
|
1532
|
+
}
|
|
1533
|
+
function onDeleteNodes(ids) {
|
|
1534
|
+
deleteNodes(ids);
|
|
1535
|
+
}
|
|
1536
|
+
function onRevertDeleteNode({ node }) {
|
|
1537
|
+
revertDeleteNode(node);
|
|
1538
|
+
}
|
|
1539
|
+
function onToggleNodeDisabled(id) {
|
|
1540
|
+
if (!checkIfEditingIsAllowed()) {
|
|
1541
|
+
return;
|
|
1542
|
+
}
|
|
1543
|
+
toggleNodesDisabled([id]);
|
|
1544
|
+
}
|
|
1545
|
+
function onRevertToggleNodeDisabled({ nodeName }) {
|
|
1546
|
+
revertToggleNodeDisabled(nodeName);
|
|
1547
|
+
}
|
|
1548
|
+
function onToggleNodesDisabled(ids) {
|
|
1549
|
+
if (!checkIfEditingIsAllowed()) {
|
|
1550
|
+
return;
|
|
1551
|
+
}
|
|
1552
|
+
toggleNodesDisabled(ids);
|
|
1553
|
+
}
|
|
1554
|
+
function onClickNode(_id, event) {
|
|
1555
|
+
lastClickPosition.value = [event.x, event.y];
|
|
1556
|
+
closeNodeCreator();
|
|
1557
|
+
}
|
|
1558
|
+
function onSetNodeActivated(id, event) {
|
|
1559
|
+
if (event?.metaKey || event?.ctrlKey) {
|
|
1560
|
+
const didOpen = tryToOpenSubworkflowInNewTab(id);
|
|
1561
|
+
if (didOpen) {
|
|
1562
|
+
return;
|
|
1563
|
+
}
|
|
1564
|
+
}
|
|
1565
|
+
setNodeActive(id);
|
|
1566
|
+
}
|
|
1567
|
+
function onOpenSubWorkflow(id) {
|
|
1568
|
+
tryToOpenSubworkflowInNewTab(id);
|
|
1569
|
+
}
|
|
1570
|
+
function onSetNodeDeactivated() {
|
|
1571
|
+
clearNodeActive();
|
|
1572
|
+
}
|
|
1573
|
+
function onSetNodeSelected(id) {
|
|
1574
|
+
closeNodeCreator();
|
|
1575
|
+
setNodeSelected(id);
|
|
1576
|
+
}
|
|
1577
|
+
async function onCopyNodes(ids) {
|
|
1578
|
+
await copyNodes(ids);
|
|
1579
|
+
toast.showMessage({ title: i18n.baseText("generic.copiedToClipboard"), type: "success" });
|
|
1580
|
+
}
|
|
1581
|
+
async function onClipboardPaste(plainTextData) {
|
|
1582
|
+
if (getNodeViewTab(route) !== MAIN_HEADER_TABS.WORKFLOW || !keyBindingsEnabled.value || !checkIfEditingIsAllowed()) {
|
|
1583
|
+
return;
|
|
1584
|
+
}
|
|
1585
|
+
let workflowData = null;
|
|
1586
|
+
if (plainTextData.match(VALID_WORKFLOW_IMPORT_URL_REGEX)) {
|
|
1587
|
+
const importConfirm = await message.confirm(
|
|
1588
|
+
i18n.baseText("nodeView.confirmMessage.onClipboardPasteEvent.message", {
|
|
1589
|
+
interpolate: { plainTextData }
|
|
1590
|
+
}),
|
|
1591
|
+
i18n.baseText("nodeView.confirmMessage.onClipboardPasteEvent.headline"),
|
|
1592
|
+
{
|
|
1593
|
+
type: "warning",
|
|
1594
|
+
confirmButtonText: i18n.baseText(
|
|
1595
|
+
"nodeView.confirmMessage.onClipboardPasteEvent.confirmButtonText"
|
|
1596
|
+
),
|
|
1597
|
+
cancelButtonText: i18n.baseText(
|
|
1598
|
+
"nodeView.confirmMessage.onClipboardPasteEvent.cancelButtonText"
|
|
1599
|
+
)
|
|
1600
|
+
}
|
|
1601
|
+
);
|
|
1602
|
+
if (importConfirm !== MODAL_CONFIRM) {
|
|
1603
|
+
return;
|
|
1604
|
+
}
|
|
1605
|
+
workflowData = await fetchWorkflowDataFromUrl(plainTextData);
|
|
1606
|
+
} else {
|
|
1607
|
+
workflowData = jsonParse(plainTextData, { fallbackValue: null });
|
|
1608
|
+
}
|
|
1609
|
+
if (!workflowData) {
|
|
1610
|
+
return;
|
|
1611
|
+
}
|
|
1612
|
+
const result = await importWorkflowData(workflowData, "paste", {
|
|
1613
|
+
importTags: false,
|
|
1614
|
+
viewport: viewportBoundaries.value
|
|
1615
|
+
});
|
|
1616
|
+
selectNodes(result.nodes?.map((node) => node.id) ?? []);
|
|
1617
|
+
}
|
|
1618
|
+
async function onCutNodes(ids) {
|
|
1619
|
+
if (isCanvasReadOnly.value) {
|
|
1620
|
+
await copyNodes(ids);
|
|
1621
|
+
} else {
|
|
1622
|
+
await cutNodes(ids);
|
|
1623
|
+
}
|
|
1624
|
+
}
|
|
1625
|
+
async function onDuplicateNodes(ids) {
|
|
1626
|
+
if (!checkIfEditingIsAllowed()) {
|
|
1627
|
+
return;
|
|
1628
|
+
}
|
|
1629
|
+
const newIds = await duplicateNodes(ids, {
|
|
1630
|
+
viewport: viewportBoundaries.value
|
|
1631
|
+
});
|
|
1632
|
+
selectNodes(newIds);
|
|
1633
|
+
}
|
|
1634
|
+
function onPinNodes(ids, source) {
|
|
1635
|
+
if (!checkIfEditingIsAllowed()) {
|
|
1636
|
+
return;
|
|
1637
|
+
}
|
|
1638
|
+
toggleNodesPinned(ids, source);
|
|
1639
|
+
}
|
|
1640
|
+
async function onSaveWorkflow() {
|
|
1641
|
+
const workflowIsSaved = !uiStore.stateIsDirty && !workflowsStore.isNewWorkflow;
|
|
1642
|
+
const workflowIsArchived = workflowsStore.workflow.isArchived;
|
|
1643
|
+
if (workflowIsSaved || workflowIsArchived) {
|
|
1644
|
+
return;
|
|
1645
|
+
}
|
|
1646
|
+
const saved = await workflowSaving.saveCurrentWorkflow();
|
|
1647
|
+
if (saved) {
|
|
1648
|
+
canvasEventBus.emit("saved:workflow");
|
|
1649
|
+
}
|
|
1650
|
+
}
|
|
1651
|
+
function addWorkflowSavedEventBindings() {
|
|
1652
|
+
canvasEventBus.on("saved:workflow", npsSurveyStore.fetchPromptsData);
|
|
1653
|
+
canvasEventBus.on("saved:workflow", onSaveFromWithinNDV);
|
|
1654
|
+
}
|
|
1655
|
+
function removeWorkflowSavedEventBindings() {
|
|
1656
|
+
canvasEventBus.off("saved:workflow", npsSurveyStore.fetchPromptsData);
|
|
1657
|
+
canvasEventBus.off("saved:workflow", onSaveFromWithinNDV);
|
|
1658
|
+
canvasEventBus.off("saved:workflow", onSaveFromWithinExecutionDebug);
|
|
1659
|
+
}
|
|
1660
|
+
async function onSaveFromWithinNDV() {
|
|
1661
|
+
if (ndvStore.activeNodeName) {
|
|
1662
|
+
toast.showMessage({
|
|
1663
|
+
title: i18n.baseText("generic.workflowSaved"),
|
|
1664
|
+
type: "success"
|
|
1665
|
+
});
|
|
1666
|
+
}
|
|
1667
|
+
}
|
|
1668
|
+
async function onCreateWorkflow() {
|
|
1669
|
+
await router.push({ name: VIEWS.NEW_WORKFLOW });
|
|
1670
|
+
}
|
|
1671
|
+
function onRenameNode(name) {
|
|
1672
|
+
if (ndvStore.activeNode?.name) {
|
|
1673
|
+
void renameNode(ndvStore.activeNode.name, name);
|
|
1674
|
+
}
|
|
1675
|
+
}
|
|
1676
|
+
async function onOpenRenameNodeModal(id) {
|
|
1677
|
+
const currentName = workflowsStore.getNodeById(id)?.name ?? "";
|
|
1678
|
+
const activeElement = document.activeElement;
|
|
1679
|
+
if (activeElement && activeElement.tagName === "INPUT") {
|
|
1680
|
+
return;
|
|
1681
|
+
}
|
|
1682
|
+
if (!keyBindingsEnabled.value || document.querySelector(".rename-prompt")) return;
|
|
1683
|
+
try {
|
|
1684
|
+
const promptResponsePromise = message.prompt(
|
|
1685
|
+
i18n.baseText("nodeView.prompt.newName") + ":",
|
|
1686
|
+
i18n.baseText("nodeView.prompt.renameNode") + `: ${currentName}`,
|
|
1687
|
+
{
|
|
1688
|
+
customClass: "rename-prompt",
|
|
1689
|
+
confirmButtonText: i18n.baseText("nodeView.prompt.rename"),
|
|
1690
|
+
cancelButtonText: i18n.baseText("nodeView.prompt.cancel"),
|
|
1691
|
+
inputErrorMessage: i18n.baseText("nodeView.prompt.invalidName"),
|
|
1692
|
+
inputValue: currentName,
|
|
1693
|
+
inputValidator: (value) => {
|
|
1694
|
+
if (!value.trim()) {
|
|
1695
|
+
return i18n.baseText("nodeView.prompt.invalidName");
|
|
1696
|
+
}
|
|
1697
|
+
return true;
|
|
1698
|
+
}
|
|
1699
|
+
}
|
|
1700
|
+
);
|
|
1701
|
+
await nextTick();
|
|
1702
|
+
const nameInput = document.querySelector(".rename-prompt .el-input__inner");
|
|
1703
|
+
nameInput?.focus();
|
|
1704
|
+
nameInput?.select();
|
|
1705
|
+
const promptResponse = await promptResponsePromise;
|
|
1706
|
+
if (promptResponse.action === MODAL_CONFIRM) {
|
|
1707
|
+
await renameNode(currentName, promptResponse.value, { trackHistory: true });
|
|
1708
|
+
}
|
|
1709
|
+
} catch (e) {
|
|
1710
|
+
}
|
|
1711
|
+
}
|
|
1712
|
+
async function onRevertRenameNode({
|
|
1713
|
+
currentName,
|
|
1714
|
+
newName
|
|
1715
|
+
}) {
|
|
1716
|
+
await revertRenameNode(currentName, newName);
|
|
1717
|
+
}
|
|
1718
|
+
async function onRevertReplaceNodeParameters({
|
|
1719
|
+
nodeId,
|
|
1720
|
+
currentProperties,
|
|
1721
|
+
newProperties
|
|
1722
|
+
}) {
|
|
1723
|
+
await revertReplaceNodeParameters(nodeId, currentProperties, newProperties);
|
|
1724
|
+
}
|
|
1725
|
+
function onUpdateNodeParameters(id, parameters) {
|
|
1726
|
+
setNodeParameters(id, parameters);
|
|
1727
|
+
}
|
|
1728
|
+
function onUpdateNodeInputs(id) {
|
|
1729
|
+
revalidateNodeInputConnections(id);
|
|
1730
|
+
}
|
|
1731
|
+
function onUpdateNodeOutputs(id) {
|
|
1732
|
+
revalidateNodeOutputConnections(id);
|
|
1733
|
+
}
|
|
1734
|
+
function onClickNodeAdd(source, sourceHandle) {
|
|
1735
|
+
nodeCreatorStore.openNodeCreatorForConnectingNode({
|
|
1736
|
+
connection: {
|
|
1737
|
+
source,
|
|
1738
|
+
sourceHandle
|
|
1739
|
+
},
|
|
1740
|
+
eventSource: NODE_CREATOR_OPEN_SOURCES.PLUS_ENDPOINT
|
|
1741
|
+
});
|
|
1742
|
+
}
|
|
1743
|
+
async function loadCredentials() {
|
|
1744
|
+
let options;
|
|
1745
|
+
if (workflowId.value) {
|
|
1746
|
+
options = { workflowId: workflowId.value };
|
|
1747
|
+
} else {
|
|
1748
|
+
const queryParam = typeof route.query?.projectId === "string" ? route.query?.projectId : void 0;
|
|
1749
|
+
const projectId = queryParam ?? projectsStore.personalProject?.id;
|
|
1750
|
+
if (projectId === void 0) {
|
|
1751
|
+
throw new Error(
|
|
1752
|
+
"Could not find projectId in the query nor could I find the personal project in the project store"
|
|
1753
|
+
);
|
|
1754
|
+
}
|
|
1755
|
+
options = { projectId };
|
|
1756
|
+
}
|
|
1757
|
+
await credentialsStore.fetchAllCredentialsForWorkflow(options);
|
|
1758
|
+
}
|
|
1759
|
+
function onCreateConnection(connection) {
|
|
1760
|
+
createConnection(connection, { trackHistory: true });
|
|
1761
|
+
}
|
|
1762
|
+
function onRevertCreateConnection({ connection }) {
|
|
1763
|
+
revertCreateConnection(connection);
|
|
1764
|
+
}
|
|
1765
|
+
function onCreateConnectionCancelled(event, position, mouseEvent) {
|
|
1766
|
+
const preventDefault = (mouseEvent?.target).classList?.contains("clickable");
|
|
1767
|
+
if (preventDefault) {
|
|
1768
|
+
return;
|
|
1769
|
+
}
|
|
1770
|
+
uiStore.lastInteractedWithNodeId = event.nodeId;
|
|
1771
|
+
uiStore.lastInteractedWithNodeHandle = event.handleId;
|
|
1772
|
+
uiStore.lastCancelledConnectionPosition = [position.x, position.y];
|
|
1773
|
+
setTimeout(() => {
|
|
1774
|
+
if (!event.nodeId) return;
|
|
1775
|
+
nodeCreatorStore.openNodeCreatorForConnectingNode({
|
|
1776
|
+
connection: {
|
|
1777
|
+
source: event.nodeId,
|
|
1778
|
+
sourceHandle: event.handleId
|
|
1779
|
+
},
|
|
1780
|
+
eventSource: NODE_CREATOR_OPEN_SOURCES.NODE_CONNECTION_DROP
|
|
1781
|
+
});
|
|
1782
|
+
});
|
|
1783
|
+
}
|
|
1784
|
+
function onDeleteConnection(connection) {
|
|
1785
|
+
deleteConnection(connection, { trackHistory: true });
|
|
1786
|
+
}
|
|
1787
|
+
function onRevertDeleteConnection({ connection }) {
|
|
1788
|
+
revertDeleteConnection(connection);
|
|
1789
|
+
}
|
|
1790
|
+
async function importWorkflowExact({ workflow: workflowData }) {
|
|
1791
|
+
if (!workflowData.nodes || !workflowData.connections) {
|
|
1792
|
+
throw new Error("Invalid workflow object");
|
|
1793
|
+
}
|
|
1794
|
+
resetWorkspace();
|
|
1795
|
+
await initializeData();
|
|
1796
|
+
initializeWorkspace({
|
|
1797
|
+
...workflowData,
|
|
1798
|
+
nodes: getNodesWithNormalizedPosition(workflowData.nodes)
|
|
1799
|
+
});
|
|
1800
|
+
fitView();
|
|
1801
|
+
}
|
|
1802
|
+
async function onImportWorkflowDataEvent(data) {
|
|
1803
|
+
const workflowData = data.data;
|
|
1804
|
+
await importWorkflowData(workflowData, "file", {
|
|
1805
|
+
viewport: viewportBoundaries.value,
|
|
1806
|
+
regenerateIds: data.regenerateIds === true || data.regenerateIds === void 0
|
|
1807
|
+
});
|
|
1808
|
+
fitView();
|
|
1809
|
+
selectNodes(workflowData.nodes?.map((node) => node.id) ?? []);
|
|
1810
|
+
if (data.tidyUp) {
|
|
1811
|
+
const nodesIdsToTidyUp = data.nodesIdsToTidyUp;
|
|
1812
|
+
setTimeout(() => {
|
|
1813
|
+
canvasEventBus.emit("tidyUp", {
|
|
1814
|
+
source: "import-workflow-data",
|
|
1815
|
+
nodeIdsFilter: nodesIdsToTidyUp
|
|
1816
|
+
});
|
|
1817
|
+
}, 0);
|
|
1818
|
+
}
|
|
1819
|
+
}
|
|
1820
|
+
async function onImportWorkflowUrlEvent(data) {
|
|
1821
|
+
const workflowData = await fetchWorkflowDataFromUrl(data.url);
|
|
1822
|
+
if (!workflowData) {
|
|
1823
|
+
return;
|
|
1824
|
+
}
|
|
1825
|
+
await importWorkflowData(workflowData, "url", {
|
|
1826
|
+
viewport: viewportBoundaries.value
|
|
1827
|
+
});
|
|
1828
|
+
fitView();
|
|
1829
|
+
selectNodes(workflowData.nodes?.map((node) => node.id) ?? []);
|
|
1830
|
+
}
|
|
1831
|
+
function addImportEventBindings() {
|
|
1832
|
+
nodeViewEventBus.on("importWorkflowData", onImportWorkflowDataEvent);
|
|
1833
|
+
nodeViewEventBus.on("importWorkflowUrl", onImportWorkflowUrlEvent);
|
|
1834
|
+
nodeViewEventBus.on("openChat", onOpenChat);
|
|
1835
|
+
}
|
|
1836
|
+
function removeImportEventBindings() {
|
|
1837
|
+
nodeViewEventBus.off("importWorkflowData", onImportWorkflowDataEvent);
|
|
1838
|
+
nodeViewEventBus.off("importWorkflowUrl", onImportWorkflowUrlEvent);
|
|
1839
|
+
nodeViewEventBus.off("openChat", onOpenChat);
|
|
1840
|
+
}
|
|
1841
|
+
async function onAddNodesAndConnections({ nodes, connections }, dragAndDrop = false, position) {
|
|
1842
|
+
if (!checkIfEditingIsAllowed()) {
|
|
1843
|
+
return;
|
|
1844
|
+
}
|
|
1845
|
+
const addedNodes = await addNodes(nodes, {
|
|
1846
|
+
dragAndDrop,
|
|
1847
|
+
position,
|
|
1848
|
+
viewport: viewportBoundaries.value,
|
|
1849
|
+
trackHistory: true,
|
|
1850
|
+
telemetry: true
|
|
1851
|
+
});
|
|
1852
|
+
const offsetIndex = editableWorkflow.value.nodes.length - nodes.length;
|
|
1853
|
+
const mappedConnections = connections.map(({ from, to }) => {
|
|
1854
|
+
const fromNode = editableWorkflow.value.nodes[offsetIndex + from.nodeIndex];
|
|
1855
|
+
const toNode = editableWorkflow.value.nodes[offsetIndex + to.nodeIndex];
|
|
1856
|
+
const type = from.type ?? to.type ?? NodeConnectionTypes.Main;
|
|
1857
|
+
return {
|
|
1858
|
+
source: fromNode.id,
|
|
1859
|
+
sourceHandle: createCanvasConnectionHandleString({
|
|
1860
|
+
mode: CanvasConnectionMode.Output,
|
|
1861
|
+
type: isValidNodeConnectionType(type) ? type : NodeConnectionTypes.Main,
|
|
1862
|
+
index: from.outputIndex ?? 0
|
|
1863
|
+
}),
|
|
1864
|
+
target: toNode.id,
|
|
1865
|
+
targetHandle: createCanvasConnectionHandleString({
|
|
1866
|
+
mode: CanvasConnectionMode.Input,
|
|
1867
|
+
type: isValidNodeConnectionType(type) ? type : NodeConnectionTypes.Main,
|
|
1868
|
+
index: to.inputIndex ?? 0
|
|
1869
|
+
}),
|
|
1870
|
+
data: {
|
|
1871
|
+
source: {
|
|
1872
|
+
index: from.outputIndex ?? 0,
|
|
1873
|
+
type
|
|
1874
|
+
},
|
|
1875
|
+
target: {
|
|
1876
|
+
index: to.inputIndex ?? 0,
|
|
1877
|
+
type
|
|
1878
|
+
}
|
|
1879
|
+
}
|
|
1880
|
+
};
|
|
1881
|
+
});
|
|
1882
|
+
await addConnections(mappedConnections);
|
|
1883
|
+
uiStore.resetLastInteractedWith();
|
|
1884
|
+
if (addedNodes.length > 0) {
|
|
1885
|
+
selectNodes([addedNodes[addedNodes.length - 1].id]);
|
|
1886
|
+
}
|
|
1887
|
+
}
|
|
1888
|
+
async function onRevertAddNode({ node }) {
|
|
1889
|
+
await revertAddNode(node.name);
|
|
1890
|
+
}
|
|
1891
|
+
function onSwitchActiveNode(nodeName) {
|
|
1892
|
+
const node = workflowsStore.getNodeByName(nodeName);
|
|
1893
|
+
if (!node) return;
|
|
1894
|
+
setNodeActiveByName(nodeName);
|
|
1895
|
+
selectNodes([node.id]);
|
|
1896
|
+
}
|
|
1897
|
+
function onOpenSelectiveNodeCreator(node, connectionType, connectionIndex = 0) {
|
|
1898
|
+
nodeCreatorStore.openSelectiveNodeCreator({ node, connectionType, connectionIndex });
|
|
1899
|
+
}
|
|
1900
|
+
function onToggleNodeCreator(options) {
|
|
1901
|
+
nodeCreatorStore.setNodeCreatorState(options);
|
|
1902
|
+
if (!options.createNodeActive && !options.hasAddedNodes) {
|
|
1903
|
+
uiStore.resetLastInteractedWith();
|
|
1904
|
+
}
|
|
1905
|
+
}
|
|
1906
|
+
function onOpenNodeCreatorFromCanvas(source) {
|
|
1907
|
+
onToggleNodeCreator({ createNodeActive: true, source });
|
|
1908
|
+
}
|
|
1909
|
+
function onOpenNodeCreatorForTriggerNodes(source) {
|
|
1910
|
+
nodeCreatorStore.openNodeCreatorForTriggerNodes(source);
|
|
1911
|
+
}
|
|
1912
|
+
function onToggleFocusPanel() {
|
|
1913
|
+
focusPanelStore.toggleFocusPanel();
|
|
1914
|
+
telemetry.track(`User ${focusPanelStore.focusPanelActive ? "opened" : "closed"} focus panel`, {
|
|
1915
|
+
source: "canvasKeyboardShortcut",
|
|
1916
|
+
parameters: focusPanelStore.focusedNodeParametersInTelemetryFormat,
|
|
1917
|
+
parameterCount: focusPanelStore.focusedNodeParametersInTelemetryFormat.length
|
|
1918
|
+
});
|
|
1919
|
+
}
|
|
1920
|
+
function closeNodeCreator() {
|
|
1921
|
+
if (nodeCreatorStore.isCreateNodeActive) {
|
|
1922
|
+
nodeCreatorStore.isCreateNodeActive = false;
|
|
1923
|
+
}
|
|
1924
|
+
}
|
|
1925
|
+
function onCreateSticky() {
|
|
1926
|
+
void onAddNodesAndConnections({ nodes: [{ type: STICKY_NODE_TYPE }], connections: [] });
|
|
1927
|
+
}
|
|
1928
|
+
function onClickConnectionAdd(connection) {
|
|
1929
|
+
nodeCreatorStore.openNodeCreatorForConnectingNode({
|
|
1930
|
+
connection,
|
|
1931
|
+
eventSource: NODE_CREATOR_OPEN_SOURCES.NODE_CONNECTION_ACTION
|
|
1932
|
+
});
|
|
1933
|
+
}
|
|
1934
|
+
const workflowPermissions = computed(() => {
|
|
1935
|
+
return workflowId.value ? getResourcePermissions(workflowsStore.getWorkflowById(workflowId.value)?.scopes).workflow : {};
|
|
1936
|
+
});
|
|
1937
|
+
const projectPermissions = computed(() => {
|
|
1938
|
+
const project = route.query?.projectId ? projectsStore.myProjects.find((p) => p.id === route.query.projectId) : projectsStore.currentProject ?? projectsStore.personalProject;
|
|
1939
|
+
return getResourcePermissions(project?.scopes);
|
|
1940
|
+
});
|
|
1941
|
+
const isStoppingExecution = ref(false);
|
|
1942
|
+
const isWorkflowRunning = computed(() => workflowsStore.isWorkflowRunning);
|
|
1943
|
+
const isExecutionWaitingForWebhook = computed(() => workflowsStore.executionWaitingForWebhook);
|
|
1944
|
+
const isExecutionDisabled = computed(() => {
|
|
1945
|
+
if (containsChatTriggerNodes.value && isOnlyChatTriggerNodeActive.value && !chatTriggerNodePinnedData.value) {
|
|
1946
|
+
return true;
|
|
1947
|
+
}
|
|
1948
|
+
return !containsTriggerNodes.value || allTriggerNodesDisabled.value;
|
|
1949
|
+
});
|
|
1950
|
+
const isRunWorkflowButtonVisible = computed(
|
|
1951
|
+
() => !isOnlyChatTriggerNodeActive.value || chatTriggerNodePinnedData.value
|
|
1952
|
+
);
|
|
1953
|
+
const isStopExecutionButtonVisible = computed(
|
|
1954
|
+
() => isWorkflowRunning.value && !isExecutionWaitingForWebhook.value
|
|
1955
|
+
);
|
|
1956
|
+
const isStopWaitingForWebhookButtonVisible = computed(
|
|
1957
|
+
() => isWorkflowRunning.value && isExecutionWaitingForWebhook.value
|
|
1958
|
+
);
|
|
1959
|
+
async function onRunWorkflowToNode(id) {
|
|
1960
|
+
const node = workflowsStore.getNodeById(id);
|
|
1961
|
+
if (!node) return;
|
|
1962
|
+
if (needsAgentInput(node) && nodeTypesStore.isToolNode(node.type)) {
|
|
1963
|
+
uiStore.openModalWithData({
|
|
1964
|
+
name: FROM_AI_PARAMETERS_MODAL_KEY,
|
|
1965
|
+
data: {
|
|
1966
|
+
nodeName: node.name
|
|
1967
|
+
}
|
|
1968
|
+
});
|
|
1969
|
+
} else {
|
|
1970
|
+
trackRunWorkflowToNode(node);
|
|
1971
|
+
agentRequestStore.clearAgentRequests(workflowsStore.workflowId, node.id);
|
|
1972
|
+
void runWorkflow({ destinationNode: node.name, source: "Node.executeNode" });
|
|
1973
|
+
}
|
|
1974
|
+
}
|
|
1975
|
+
function trackRunWorkflowToNode(node) {
|
|
1976
|
+
const telemetryPayload = {
|
|
1977
|
+
node_type: node.type,
|
|
1978
|
+
workflow_id: workflowsStore.workflowId,
|
|
1979
|
+
source: "canvas",
|
|
1980
|
+
push_ref: ndvStore.pushRef
|
|
1981
|
+
};
|
|
1982
|
+
telemetry.track("User clicked execute node button", telemetryPayload);
|
|
1983
|
+
void externalHooks.run("nodeView.onRunNode", telemetryPayload);
|
|
1984
|
+
}
|
|
1985
|
+
async function onOpenExecution(executionId, nodeId) {
|
|
1986
|
+
canvasStore.startLoading();
|
|
1987
|
+
resetWorkspace();
|
|
1988
|
+
await initializeData();
|
|
1989
|
+
const data = await openExecution(executionId, nodeId);
|
|
1990
|
+
if (!data) {
|
|
1991
|
+
return;
|
|
1992
|
+
}
|
|
1993
|
+
void nextTick(() => {
|
|
1994
|
+
updateNodesIssues();
|
|
1995
|
+
});
|
|
1996
|
+
canvasStore.stopLoading();
|
|
1997
|
+
fitView();
|
|
1998
|
+
canvasEventBus.emit("open:execution", data);
|
|
1999
|
+
void externalHooks.run("execution.open", {
|
|
2000
|
+
workflowId: data.workflowData.id,
|
|
2001
|
+
workflowName: data.workflowData.name,
|
|
2002
|
+
executionId
|
|
2003
|
+
});
|
|
2004
|
+
telemetry.track("User opened read-only execution", {
|
|
2005
|
+
workflow_id: data.workflowData.id,
|
|
2006
|
+
execution_mode: data.mode,
|
|
2007
|
+
execution_finished: data.finished
|
|
2008
|
+
});
|
|
2009
|
+
}
|
|
2010
|
+
function onExecutionOpenedWithError(data) {
|
|
2011
|
+
if (!data.finished && data.data?.resultData?.error) {
|
|
2012
|
+
let nodeErrorFound = false;
|
|
2013
|
+
if (data.data.resultData.runData) {
|
|
2014
|
+
const runData = data.data.resultData.runData;
|
|
2015
|
+
errorCheck: for (const nodeName of Object.keys(runData)) {
|
|
2016
|
+
for (const taskData of runData[nodeName]) {
|
|
2017
|
+
if (taskData.error) {
|
|
2018
|
+
nodeErrorFound = true;
|
|
2019
|
+
break errorCheck;
|
|
2020
|
+
}
|
|
2021
|
+
}
|
|
2022
|
+
}
|
|
2023
|
+
}
|
|
2024
|
+
if (!nodeErrorFound && (data.data.resultData.error.stack ?? data.data.resultData.error.message)) {
|
|
2025
|
+
console.error(`Execution ${data.id} error:`);
|
|
2026
|
+
console.error(data.data.resultData.error.stack);
|
|
2027
|
+
toast.showMessage({
|
|
2028
|
+
title: i18n.baseText("nodeView.showError.workflowError"),
|
|
2029
|
+
message: data.data.resultData.error.message,
|
|
2030
|
+
type: "error",
|
|
2031
|
+
duration: 0
|
|
2032
|
+
});
|
|
2033
|
+
}
|
|
2034
|
+
}
|
|
2035
|
+
}
|
|
2036
|
+
function onExecutionOpenedWithWaitTill(data) {
|
|
2037
|
+
if (data.waitTill) {
|
|
2038
|
+
toast.showMessage({
|
|
2039
|
+
title: i18n.baseText("nodeView.thisExecutionHasntFinishedYet"),
|
|
2040
|
+
message: h(_sfc_main$2),
|
|
2041
|
+
type: "warning",
|
|
2042
|
+
duration: 0
|
|
2043
|
+
});
|
|
2044
|
+
}
|
|
2045
|
+
}
|
|
2046
|
+
function addExecutionOpenedEventBindings() {
|
|
2047
|
+
canvasEventBus.on("open:execution", onExecutionOpenedWithError);
|
|
2048
|
+
canvasEventBus.on("open:execution", onExecutionOpenedWithWaitTill);
|
|
2049
|
+
}
|
|
2050
|
+
function removeExecutionOpenedEventBindings() {
|
|
2051
|
+
canvasEventBus.off("open:execution", onExecutionOpenedWithError);
|
|
2052
|
+
canvasEventBus.off("open:execution", onExecutionOpenedWithWaitTill);
|
|
2053
|
+
}
|
|
2054
|
+
async function onStopExecution() {
|
|
2055
|
+
isStoppingExecution.value = true;
|
|
2056
|
+
await stopCurrentExecution();
|
|
2057
|
+
isStoppingExecution.value = false;
|
|
2058
|
+
}
|
|
2059
|
+
async function onStopWaitingForWebhook() {
|
|
2060
|
+
await stopWaitingForWebhook();
|
|
2061
|
+
}
|
|
2062
|
+
function onRunWorkflowButtonMouseEnter() {
|
|
2063
|
+
nodeViewEventBus.emit("runWorkflowButton:mouseenter");
|
|
2064
|
+
}
|
|
2065
|
+
function onRunWorkflowButtonMouseLeave() {
|
|
2066
|
+
nodeViewEventBus.emit("runWorkflowButton:mouseleave");
|
|
2067
|
+
}
|
|
2068
|
+
const chatTriggerNode = computed(() => {
|
|
2069
|
+
return editableWorkflow.value.nodes.find((node) => node.type === CHAT_TRIGGER_NODE_TYPE);
|
|
2070
|
+
});
|
|
2071
|
+
const containsChatTriggerNodes = computed(() => {
|
|
2072
|
+
return !isExecutionWaitingForWebhook.value && !!editableWorkflow.value.nodes.find(
|
|
2073
|
+
(node) => [MANUAL_CHAT_TRIGGER_NODE_TYPE, CHAT_TRIGGER_NODE_TYPE].includes(node.type) && node.disabled !== true
|
|
2074
|
+
);
|
|
2075
|
+
});
|
|
2076
|
+
const isOnlyChatTriggerNodeActive = computed(() => {
|
|
2077
|
+
return triggerNodes.value.every((node) => node.disabled || node.type === CHAT_TRIGGER_NODE_TYPE);
|
|
2078
|
+
});
|
|
2079
|
+
const chatTriggerNodePinnedData = computed(() => {
|
|
2080
|
+
if (!chatTriggerNode.value) return null;
|
|
2081
|
+
return workflowsStore.pinDataByNodeName(chatTriggerNode.value.name);
|
|
2082
|
+
});
|
|
2083
|
+
function onOpenChat() {
|
|
2084
|
+
startChat("main");
|
|
2085
|
+
}
|
|
2086
|
+
const evaluationTriggerNode = computed(() => {
|
|
2087
|
+
return editableWorkflow.value.nodes.find((node) => node.type === EVALUATION_TRIGGER_NODE_TYPE);
|
|
2088
|
+
});
|
|
2089
|
+
function addUndoRedoEventBindings() {
|
|
2090
|
+
historyBus.on("nodeMove", onRevertNodePosition);
|
|
2091
|
+
historyBus.on("revertAddNode", onRevertAddNode);
|
|
2092
|
+
historyBus.on("revertRemoveNode", onRevertDeleteNode);
|
|
2093
|
+
historyBus.on("revertAddConnection", onRevertCreateConnection);
|
|
2094
|
+
historyBus.on("revertRemoveConnection", onRevertDeleteConnection);
|
|
2095
|
+
historyBus.on("revertRenameNode", onRevertRenameNode);
|
|
2096
|
+
historyBus.on("revertReplaceNodeParameters", onRevertReplaceNodeParameters);
|
|
2097
|
+
historyBus.on("enableNodeToggle", onRevertToggleNodeDisabled);
|
|
2098
|
+
}
|
|
2099
|
+
function removeUndoRedoEventBindings() {
|
|
2100
|
+
historyBus.off("nodeMove", onRevertNodePosition);
|
|
2101
|
+
historyBus.off("revertAddNode", onRevertAddNode);
|
|
2102
|
+
historyBus.off("revertRemoveNode", onRevertDeleteNode);
|
|
2103
|
+
historyBus.off("revertAddConnection", onRevertCreateConnection);
|
|
2104
|
+
historyBus.off("revertRemoveConnection", onRevertDeleteConnection);
|
|
2105
|
+
historyBus.off("revertRenameNode", onRevertRenameNode);
|
|
2106
|
+
historyBus.off("revertReplaceNodeParameters", onRevertReplaceNodeParameters);
|
|
2107
|
+
historyBus.off("enableNodeToggle", onRevertToggleNodeDisabled);
|
|
2108
|
+
}
|
|
2109
|
+
async function onSourceControlPull() {
|
|
2110
|
+
try {
|
|
2111
|
+
await Promise.all([
|
|
2112
|
+
environmentsStore.fetchAllVariables(),
|
|
2113
|
+
tagsStore.fetchAll(),
|
|
2114
|
+
loadCredentials()
|
|
2115
|
+
]);
|
|
2116
|
+
if (workflowId.value && !uiStore.stateIsDirty) {
|
|
2117
|
+
const workflowData = await workflowsStore.fetchWorkflow(workflowId.value);
|
|
2118
|
+
if (workflowData) {
|
|
2119
|
+
workflowHelpers.setDocumentTitle(workflowData.name, "IDLE");
|
|
2120
|
+
openWorkflow(workflowData);
|
|
2121
|
+
}
|
|
2122
|
+
}
|
|
2123
|
+
} catch (error) {
|
|
2124
|
+
console.error(error);
|
|
2125
|
+
}
|
|
2126
|
+
}
|
|
2127
|
+
function addSourceControlEventBindings() {
|
|
2128
|
+
sourceControlEventBus.on("pull", onSourceControlPull);
|
|
2129
|
+
}
|
|
2130
|
+
function removeSourceControlEventBindings() {
|
|
2131
|
+
sourceControlEventBus.off("pull", onSourceControlPull);
|
|
2132
|
+
}
|
|
2133
|
+
function addPostMessageEventBindings() {
|
|
2134
|
+
window.addEventListener("message", onPostMessageReceived);
|
|
2135
|
+
}
|
|
2136
|
+
function removePostMessageEventBindings() {
|
|
2137
|
+
window.removeEventListener("message", onPostMessageReceived);
|
|
2138
|
+
}
|
|
2139
|
+
function emitPostMessageReady() {
|
|
2140
|
+
if (window.parent) {
|
|
2141
|
+
window.parent.postMessage(
|
|
2142
|
+
JSON.stringify({ command: "n8nReady", version: rootStore.versionCli }),
|
|
2143
|
+
"*"
|
|
2144
|
+
);
|
|
2145
|
+
}
|
|
2146
|
+
}
|
|
2147
|
+
async function onPostMessageReceived(messageEvent) {
|
|
2148
|
+
if (!messageEvent || typeof messageEvent.data !== "string" || !messageEvent.data?.includes?.('"command"')) {
|
|
2149
|
+
return;
|
|
2150
|
+
}
|
|
2151
|
+
try {
|
|
2152
|
+
const json = JSON.parse(messageEvent.data);
|
|
2153
|
+
if (json && json.command === "openWorkflow") {
|
|
2154
|
+
try {
|
|
2155
|
+
await importWorkflowExact(json);
|
|
2156
|
+
canOpenNDV.value = json.canOpenNDV ?? true;
|
|
2157
|
+
hideNodeIssues.value = json.hideNodeIssues ?? false;
|
|
2158
|
+
isExecutionPreview.value = false;
|
|
2159
|
+
} catch (e) {
|
|
2160
|
+
if (window.top) {
|
|
2161
|
+
window.top.postMessage(
|
|
2162
|
+
JSON.stringify({
|
|
2163
|
+
command: "error",
|
|
2164
|
+
message: i18n.baseText("openWorkflow.workflowImportError")
|
|
2165
|
+
}),
|
|
2166
|
+
"*"
|
|
2167
|
+
);
|
|
2168
|
+
}
|
|
2169
|
+
toast.showError(e, i18n.baseText("openWorkflow.workflowImportError"));
|
|
2170
|
+
}
|
|
2171
|
+
} else if (json && json.command === "openExecution") {
|
|
2172
|
+
try {
|
|
2173
|
+
isProductionExecutionPreview.value = json.executionMode !== "manual" && json.executionMode !== "evaluation";
|
|
2174
|
+
await onOpenExecution(json.executionId, json.nodeId);
|
|
2175
|
+
canOpenNDV.value = json.canOpenNDV ?? true;
|
|
2176
|
+
hideNodeIssues.value = json.hideNodeIssues ?? false;
|
|
2177
|
+
isExecutionPreview.value = true;
|
|
2178
|
+
} catch (e) {
|
|
2179
|
+
if (window.top) {
|
|
2180
|
+
window.top.postMessage(
|
|
2181
|
+
JSON.stringify({
|
|
2182
|
+
command: "error",
|
|
2183
|
+
message: i18n.baseText("nodeView.showError.openExecution.title")
|
|
2184
|
+
}),
|
|
2185
|
+
"*"
|
|
2186
|
+
);
|
|
2187
|
+
}
|
|
2188
|
+
toast.showMessage({
|
|
2189
|
+
title: i18n.baseText("nodeView.showError.openExecution.title"),
|
|
2190
|
+
message: e.message,
|
|
2191
|
+
type: "error"
|
|
2192
|
+
});
|
|
2193
|
+
}
|
|
2194
|
+
} else if (json?.command === "setActiveExecution") {
|
|
2195
|
+
executionsStore.activeExecution = await executionsStore.fetchExecution(
|
|
2196
|
+
json.executionId
|
|
2197
|
+
);
|
|
2198
|
+
}
|
|
2199
|
+
} catch (e) {
|
|
2200
|
+
}
|
|
2201
|
+
}
|
|
2202
|
+
function checkIfEditingIsAllowed() {
|
|
2203
|
+
if (!initializedWorkflowId.value) {
|
|
2204
|
+
return true;
|
|
2205
|
+
}
|
|
2206
|
+
if (readOnlyNotification.value?.visible) {
|
|
2207
|
+
return false;
|
|
2208
|
+
}
|
|
2209
|
+
if (isReadOnlyRoute.value || isReadOnlyEnvironment.value) {
|
|
2210
|
+
const messageContext = isReadOnlyRoute.value ? "executions" : "workflows";
|
|
2211
|
+
readOnlyNotification.value = toast.showMessage({
|
|
2212
|
+
title: i18n.baseText(
|
|
2213
|
+
isReadOnlyEnvironment.value ? `readOnlyEnv.showMessage.${messageContext}.title` : "readOnly.showMessage.executions.title"
|
|
2214
|
+
),
|
|
2215
|
+
message: i18n.baseText(
|
|
2216
|
+
isReadOnlyEnvironment.value ? `readOnlyEnv.showMessage.${messageContext}.message` : "readOnly.showMessage.executions.message"
|
|
2217
|
+
),
|
|
2218
|
+
type: "info"
|
|
2219
|
+
});
|
|
2220
|
+
return false;
|
|
2221
|
+
}
|
|
2222
|
+
return true;
|
|
2223
|
+
}
|
|
2224
|
+
function checkIfRouteIsAllowed() {
|
|
2225
|
+
if (isReadOnlyEnvironment.value && [VIEWS.NEW_WORKFLOW, VIEWS.TEMPLATE_IMPORT].find((view) => view === route.name)) {
|
|
2226
|
+
void nextTick(async () => {
|
|
2227
|
+
resetWorkspace();
|
|
2228
|
+
uiStore.stateIsDirty = false;
|
|
2229
|
+
await router.replace({ name: VIEWS.HOMEPAGE });
|
|
2230
|
+
});
|
|
2231
|
+
}
|
|
2232
|
+
}
|
|
2233
|
+
async function initializeDebugMode() {
|
|
2234
|
+
workflowHelpers.setDocumentTitle(workflowsStore.workflowName, "DEBUG");
|
|
2235
|
+
if (!workflowsStore.isInDebugMode) {
|
|
2236
|
+
await applyExecutionData(route.params.executionId);
|
|
2237
|
+
workflowsStore.isInDebugMode = true;
|
|
2238
|
+
}
|
|
2239
|
+
canvasEventBus.on("saved:workflow", onSaveFromWithinExecutionDebug);
|
|
2240
|
+
}
|
|
2241
|
+
async function onSaveFromWithinExecutionDebug() {
|
|
2242
|
+
if (route.name !== VIEWS.EXECUTION_DEBUG) return;
|
|
2243
|
+
await router.replace({
|
|
2244
|
+
name: VIEWS.WORKFLOW,
|
|
2245
|
+
params: { name: workflowId.value }
|
|
2246
|
+
});
|
|
2247
|
+
}
|
|
2248
|
+
const viewportTransform = ref({ x: 0, y: 0, zoom: 1 });
|
|
2249
|
+
const viewportDimensions = ref({ width: 0, height: 0 });
|
|
2250
|
+
const viewportBoundaries = computed(
|
|
2251
|
+
() => getBounds(viewportTransform.value, viewportDimensions.value)
|
|
2252
|
+
);
|
|
2253
|
+
function onViewportChange(viewport, dimensions) {
|
|
2254
|
+
viewportTransform.value = viewport;
|
|
2255
|
+
viewportDimensions.value = dimensions;
|
|
2256
|
+
uiStore.nodeViewOffsetPosition = [viewport.x, viewport.y];
|
|
2257
|
+
}
|
|
2258
|
+
function fitView() {
|
|
2259
|
+
setTimeout(() => canvasEventBus.emit("fitView"));
|
|
2260
|
+
}
|
|
2261
|
+
function selectNodes(ids) {
|
|
2262
|
+
setTimeout(() => canvasEventBus.emit("nodes:select", { ids }));
|
|
2263
|
+
}
|
|
2264
|
+
function onClickPane(position) {
|
|
2265
|
+
lastClickPosition.value = [position.x, position.y];
|
|
2266
|
+
onSetNodeSelected();
|
|
2267
|
+
}
|
|
2268
|
+
function onSelectionEnd(position) {
|
|
2269
|
+
lastClickPosition.value = [position.x, position.y];
|
|
2270
|
+
}
|
|
2271
|
+
async function onDragAndDrop(position, event) {
|
|
2272
|
+
if (!event.dataTransfer) {
|
|
2273
|
+
return;
|
|
2274
|
+
}
|
|
2275
|
+
const dropData = jsonParse(
|
|
2276
|
+
event.dataTransfer.getData(DRAG_EVENT_DATA_KEY)
|
|
2277
|
+
);
|
|
2278
|
+
if (dropData) {
|
|
2279
|
+
const insertNodePosition = [position.x, position.y];
|
|
2280
|
+
await onAddNodesAndConnections(dropData, true, insertNodePosition);
|
|
2281
|
+
onToggleNodeCreator({ createNodeActive: false, hasAddedNodes: true });
|
|
2282
|
+
}
|
|
2283
|
+
}
|
|
2284
|
+
function registerCustomActions() {
|
|
2285
|
+
registerCustomAction({
|
|
2286
|
+
key: "openNodeDetail",
|
|
2287
|
+
action: ({ node }) => {
|
|
2288
|
+
setNodeActiveByName(node);
|
|
2289
|
+
}
|
|
2290
|
+
});
|
|
2291
|
+
registerCustomAction({
|
|
2292
|
+
key: "openSelectiveNodeCreator",
|
|
2293
|
+
action: ({
|
|
2294
|
+
creatorview: creatorView,
|
|
2295
|
+
connectiontype: connectionType,
|
|
2296
|
+
node
|
|
2297
|
+
}) => {
|
|
2298
|
+
nodeCreatorStore.openSelectiveNodeCreator({ node, connectionType, creatorView });
|
|
2299
|
+
}
|
|
2300
|
+
});
|
|
2301
|
+
registerCustomAction({
|
|
2302
|
+
key: "showNodeCreator",
|
|
2303
|
+
action: () => {
|
|
2304
|
+
ndvStore.activeNodeName = null;
|
|
2305
|
+
void nextTick(() => {
|
|
2306
|
+
void onOpenNodeCreatorForTriggerNodes(NODE_CREATOR_OPEN_SOURCES.TAB);
|
|
2307
|
+
});
|
|
2308
|
+
}
|
|
2309
|
+
});
|
|
2310
|
+
}
|
|
2311
|
+
function unregisterCustomActions() {
|
|
2312
|
+
unregisterCustomAction("openNodeDetail");
|
|
2313
|
+
unregisterCustomAction("openSelectiveNodeCreator");
|
|
2314
|
+
unregisterCustomAction("showNodeCreator");
|
|
2315
|
+
}
|
|
2316
|
+
function showAddFirstStepIfEnabled() {
|
|
2317
|
+
if (uiStore.addFirstStepOnLoad) {
|
|
2318
|
+
void onOpenNodeCreatorForTriggerNodes(NODE_CREATOR_OPEN_SOURCES.TRIGGER_PLACEHOLDER_BUTTON);
|
|
2319
|
+
uiStore.addFirstStepOnLoad = false;
|
|
2320
|
+
}
|
|
2321
|
+
}
|
|
2322
|
+
function updateNodeRoute(nodeId) {
|
|
2323
|
+
const nodeUi = workflowsStore.findNodeByPartialId(nodeId);
|
|
2324
|
+
if (nodeUi) {
|
|
2325
|
+
setNodeActive(nodeUi.id);
|
|
2326
|
+
} else {
|
|
2327
|
+
toast.showToast({
|
|
2328
|
+
title: i18n.baseText("nodeView.showMessage.ndvUrl.missingNodes.title"),
|
|
2329
|
+
message: i18n.baseText("nodeView.showMessage.ndvUrl.missingNodes.content"),
|
|
2330
|
+
type: "warning"
|
|
2331
|
+
});
|
|
2332
|
+
void router.replace({
|
|
2333
|
+
name: route.name,
|
|
2334
|
+
params: { name: workflowId.value }
|
|
2335
|
+
});
|
|
2336
|
+
}
|
|
2337
|
+
}
|
|
2338
|
+
watch(
|
|
2339
|
+
() => route.name,
|
|
2340
|
+
async (newRouteName, oldRouteName) => {
|
|
2341
|
+
const force = newRouteName === VIEWS.NEW_WORKFLOW && oldRouteName === VIEWS.WORKFLOW || newRouteName === VIEWS.WORKFLOW && oldRouteName === VIEWS.NEW_WORKFLOW;
|
|
2342
|
+
await initializeRoute(force);
|
|
2343
|
+
}
|
|
2344
|
+
);
|
|
2345
|
+
watch(
|
|
2346
|
+
() => {
|
|
2347
|
+
return isLoading.value || isCanvasReadOnly.value || editableWorkflow.value.nodes.length !== 0;
|
|
2348
|
+
},
|
|
2349
|
+
(isReadOnlyOrLoading) => {
|
|
2350
|
+
const defaultFallbackNodes = [
|
|
2351
|
+
{
|
|
2352
|
+
id: CanvasNodeRenderType.AddNodes,
|
|
2353
|
+
name: CanvasNodeRenderType.AddNodes,
|
|
2354
|
+
type: CanvasNodeRenderType.AddNodes,
|
|
2355
|
+
typeVersion: 1,
|
|
2356
|
+
position: [0, 0],
|
|
2357
|
+
parameters: {}
|
|
2358
|
+
}
|
|
2359
|
+
];
|
|
2360
|
+
if (builderStore.isAIBuilderEnabled && builderStore.isAssistantEnabled) {
|
|
2361
|
+
defaultFallbackNodes.unshift({
|
|
2362
|
+
id: CanvasNodeRenderType.AIPrompt,
|
|
2363
|
+
name: CanvasNodeRenderType.AIPrompt,
|
|
2364
|
+
type: CanvasNodeRenderType.AIPrompt,
|
|
2365
|
+
typeVersion: 1,
|
|
2366
|
+
position: [-690, -15],
|
|
2367
|
+
parameters: {}
|
|
2368
|
+
});
|
|
2369
|
+
}
|
|
2370
|
+
fallbackNodes.value = isReadOnlyOrLoading ? [] : defaultFallbackNodes;
|
|
2371
|
+
}
|
|
2372
|
+
);
|
|
2373
|
+
watch(
|
|
2374
|
+
() => route.params.nodeId,
|
|
2375
|
+
async (newId) => {
|
|
2376
|
+
if (typeof newId !== "string" || newId === "") ndvStore.activeNodeName = null;
|
|
2377
|
+
else {
|
|
2378
|
+
updateNodeRoute(newId);
|
|
2379
|
+
}
|
|
2380
|
+
}
|
|
2381
|
+
);
|
|
2382
|
+
watch(
|
|
2383
|
+
() => ndvStore.activeNode,
|
|
2384
|
+
async (val) => {
|
|
2385
|
+
if (![VIEWS.WORKFLOW].includes(String(route.name))) return;
|
|
2386
|
+
const nodeId = val?.id ? workflowsStore.getPartialIdForNode(val?.id) : "";
|
|
2387
|
+
if (nodeId !== route.params.nodeId) {
|
|
2388
|
+
await router.replace({
|
|
2389
|
+
name: route.name,
|
|
2390
|
+
params: { name: workflowId.value, nodeId }
|
|
2391
|
+
});
|
|
2392
|
+
}
|
|
2393
|
+
}
|
|
2394
|
+
);
|
|
2395
|
+
onBeforeRouteLeave(async (to, from, next) => {
|
|
2396
|
+
const toNodeViewTab = getNodeViewTab(to);
|
|
2397
|
+
if (toNodeViewTab === MAIN_HEADER_TABS.EXECUTIONS || from.name === VIEWS.TEMPLATE_IMPORT || toNodeViewTab === MAIN_HEADER_TABS.WORKFLOW && from.name === VIEWS.EXECUTION_DEBUG || isReadOnlyEnvironment.value) {
|
|
2398
|
+
next();
|
|
2399
|
+
return;
|
|
2400
|
+
}
|
|
2401
|
+
await useWorkflowSaving({ router }).promptSaveUnsavedWorkflowChanges(next, {
|
|
2402
|
+
async confirm() {
|
|
2403
|
+
if (from.name === VIEWS.NEW_WORKFLOW) {
|
|
2404
|
+
const savedWorkflowId = workflowsStore.workflowId;
|
|
2405
|
+
await router.replace({
|
|
2406
|
+
name: VIEWS.WORKFLOW,
|
|
2407
|
+
params: { name: savedWorkflowId }
|
|
2408
|
+
});
|
|
2409
|
+
await router.push(to);
|
|
2410
|
+
return false;
|
|
2411
|
+
}
|
|
2412
|
+
workflowsStore.setWorkflowId(PLACEHOLDER_EMPTY_WORKFLOW_ID);
|
|
2413
|
+
return true;
|
|
2414
|
+
}
|
|
2415
|
+
});
|
|
2416
|
+
});
|
|
2417
|
+
onBeforeMount(() => {
|
|
2418
|
+
if (!isDemoRoute.value) {
|
|
2419
|
+
pushConnectionStore.pushConnect();
|
|
2420
|
+
}
|
|
2421
|
+
addPostMessageEventBindings();
|
|
2422
|
+
});
|
|
2423
|
+
onMounted(() => {
|
|
2424
|
+
canvasStore.startLoading();
|
|
2425
|
+
documentTitle.reset();
|
|
2426
|
+
resetWorkspace();
|
|
2427
|
+
void initializeData().then(() => {
|
|
2428
|
+
void initializeRoute().then(() => {
|
|
2429
|
+
toast.showNotificationForViews([VIEWS.WORKFLOW, VIEWS.NEW_WORKFLOW]);
|
|
2430
|
+
if (route.query.settings) {
|
|
2431
|
+
uiStore.openModal(WORKFLOW_SETTINGS_MODAL_KEY);
|
|
2432
|
+
void router.replace({ query: { settings: void 0 } });
|
|
2433
|
+
}
|
|
2434
|
+
}).finally(() => {
|
|
2435
|
+
isLoading.value = false;
|
|
2436
|
+
canvasStore.stopLoading();
|
|
2437
|
+
void externalHooks.run("nodeView.mount").catch(() => {
|
|
2438
|
+
});
|
|
2439
|
+
setTimeout(() => {
|
|
2440
|
+
if (routeNodeId.value) {
|
|
2441
|
+
updateNodeRoute(routeNodeId.value);
|
|
2442
|
+
}
|
|
2443
|
+
}, 500);
|
|
2444
|
+
emitPostMessageReady();
|
|
2445
|
+
});
|
|
2446
|
+
void usersStore.showPersonalizationSurvey();
|
|
2447
|
+
checkIfRouteIsAllowed();
|
|
2448
|
+
});
|
|
2449
|
+
addSourceControlEventBindings();
|
|
2450
|
+
addWorkflowSavedEventBindings();
|
|
2451
|
+
addBeforeUnloadEventBindings();
|
|
2452
|
+
addImportEventBindings();
|
|
2453
|
+
addExecutionOpenedEventBindings();
|
|
2454
|
+
registerCustomActions();
|
|
2455
|
+
});
|
|
2456
|
+
onActivated(async () => {
|
|
2457
|
+
addUndoRedoEventBindings();
|
|
2458
|
+
showAddFirstStepIfEnabled();
|
|
2459
|
+
});
|
|
2460
|
+
onDeactivated(() => {
|
|
2461
|
+
uiStore.closeModal(WORKFLOW_SETTINGS_MODAL_KEY);
|
|
2462
|
+
removeUndoRedoEventBindings();
|
|
2463
|
+
});
|
|
2464
|
+
onBeforeUnmount(() => {
|
|
2465
|
+
removeSourceControlEventBindings();
|
|
2466
|
+
removePostMessageEventBindings();
|
|
2467
|
+
removeWorkflowSavedEventBindings();
|
|
2468
|
+
removeBeforeUnloadEventBindings();
|
|
2469
|
+
removeImportEventBindings();
|
|
2470
|
+
removeExecutionOpenedEventBindings();
|
|
2471
|
+
unregisterCustomActions();
|
|
2472
|
+
if (!isDemoRoute.value) {
|
|
2473
|
+
pushConnectionStore.pushDisconnect();
|
|
2474
|
+
}
|
|
2475
|
+
});
|
|
2476
|
+
return (_ctx, _cache) => {
|
|
2477
|
+
return openBlock(), createElementBlock("div", {
|
|
2478
|
+
class: normalizeClass(unref($style).wrapper)
|
|
2479
|
+
}, [
|
|
2480
|
+
unref(editableWorkflow) && unref(editableWorkflowObject) && !isLoading.value ? (openBlock(), createBlock(WorkflowCanvas, {
|
|
2481
|
+
key: 0,
|
|
2482
|
+
id: unref(editableWorkflow).id,
|
|
2483
|
+
workflow: unref(editableWorkflow),
|
|
2484
|
+
"workflow-object": unref(editableWorkflowObject),
|
|
2485
|
+
"fallback-nodes": fallbackNodes.value,
|
|
2486
|
+
"show-fallback-nodes": showFallbackNodes.value,
|
|
2487
|
+
"event-bus": unref(canvasEventBus),
|
|
2488
|
+
"read-only": isCanvasReadOnly.value,
|
|
2489
|
+
executing: isWorkflowRunning.value,
|
|
2490
|
+
"key-bindings": keyBindingsEnabled.value,
|
|
2491
|
+
"onUpdate:nodes:position": onUpdateNodesPosition,
|
|
2492
|
+
"onUpdate:node:position": onUpdateNodePosition,
|
|
2493
|
+
"onUpdate:node:activated": onSetNodeActivated,
|
|
2494
|
+
"onUpdate:node:deactivated": onSetNodeDeactivated,
|
|
2495
|
+
"onUpdate:node:selected": onSetNodeSelected,
|
|
2496
|
+
"onUpdate:node:enabled": onToggleNodeDisabled,
|
|
2497
|
+
"onUpdate:node:name": onOpenRenameNodeModal,
|
|
2498
|
+
"onUpdate:node:parameters": onUpdateNodeParameters,
|
|
2499
|
+
"onUpdate:node:inputs": onUpdateNodeInputs,
|
|
2500
|
+
"onUpdate:node:outputs": onUpdateNodeOutputs,
|
|
2501
|
+
"onUpdate:logsOpen": _cache[3] || (_cache[3] = ($event) => unref(logsStore).toggleOpen($event)),
|
|
2502
|
+
"onUpdate:logs:inputOpen": unref(logsStore).toggleInputOpen,
|
|
2503
|
+
"onUpdate:logs:outputOpen": unref(logsStore).toggleOutputOpen,
|
|
2504
|
+
"onUpdate:hasRangeSelection": unref(canvasStore).setHasRangeSelection,
|
|
2505
|
+
"onOpen:subWorkflow": onOpenSubWorkflow,
|
|
2506
|
+
"onClick:node": onClickNode,
|
|
2507
|
+
"onClick:node:add": onClickNodeAdd,
|
|
2508
|
+
"onRun:node": onRunWorkflowToNode,
|
|
2509
|
+
"onDelete:node": onDeleteNode,
|
|
2510
|
+
"onCreate:connection": onCreateConnection,
|
|
2511
|
+
"onCreate:connection:cancelled": onCreateConnectionCancelled,
|
|
2512
|
+
"onDelete:connection": onDeleteConnection,
|
|
2513
|
+
"onClick:connection:add": onClickConnectionAdd,
|
|
2514
|
+
"onClick:pane": onClickPane,
|
|
2515
|
+
"onCreate:node": onOpenNodeCreatorFromCanvas,
|
|
2516
|
+
"onCreate:sticky": onCreateSticky,
|
|
2517
|
+
"onDelete:nodes": onDeleteNodes,
|
|
2518
|
+
"onUpdate:nodes:enabled": onToggleNodesDisabled,
|
|
2519
|
+
"onUpdate:nodes:pin": onPinNodes,
|
|
2520
|
+
"onDuplicate:nodes": onDuplicateNodes,
|
|
2521
|
+
"onCopy:nodes": onCopyNodes,
|
|
2522
|
+
"onCut:nodes": onCutNodes,
|
|
2523
|
+
"onRun:workflow": _cache[4] || (_cache[4] = ($event) => unref(runEntireWorkflow)("main")),
|
|
2524
|
+
"onSave:workflow": onSaveWorkflow,
|
|
2525
|
+
"onCreate:workflow": onCreateWorkflow,
|
|
2526
|
+
"onViewport:change": onViewportChange,
|
|
2527
|
+
"onSelection:end": onSelectionEnd,
|
|
2528
|
+
onDragAndDrop,
|
|
2529
|
+
onTidyUp,
|
|
2530
|
+
"onToggle:focusPanel": onToggleFocusPanel,
|
|
2531
|
+
onExtractWorkflow,
|
|
2532
|
+
onStartChat: _cache[5] || (_cache[5] = ($event) => unref(startChat)())
|
|
2533
|
+
}, {
|
|
2534
|
+
default: withCtx(() => [
|
|
2535
|
+
(openBlock(), createBlock(Suspense, null, {
|
|
2536
|
+
default: withCtx(() => [
|
|
2537
|
+
createVNode(unref(LazySetupWorkflowCredentialsButton), {
|
|
2538
|
+
class: normalizeClass(unref($style).setupCredentialsButtonWrapper)
|
|
2539
|
+
}, null, 8, ["class"])
|
|
2540
|
+
]),
|
|
2541
|
+
_: 1
|
|
2542
|
+
})),
|
|
2543
|
+
!isCanvasReadOnly.value ? (openBlock(), createElementBlock("div", {
|
|
2544
|
+
key: 0,
|
|
2545
|
+
class: normalizeClass(unref($style).executionButtons)
|
|
2546
|
+
}, [
|
|
2547
|
+
isRunWorkflowButtonVisible.value ? (openBlock(), createBlock(CanvasRunWorkflowButton, {
|
|
2548
|
+
key: 0,
|
|
2549
|
+
"waiting-for-webhook": isExecutionWaitingForWebhook.value,
|
|
2550
|
+
disabled: isExecutionDisabled.value,
|
|
2551
|
+
executing: isWorkflowRunning.value,
|
|
2552
|
+
"trigger-nodes": triggerNodes.value,
|
|
2553
|
+
"get-node-type": unref(nodeTypesStore).getNodeType,
|
|
2554
|
+
"selected-trigger-node-name": unref(workflowsStore).selectedTriggerNodeName,
|
|
2555
|
+
onMouseenter: onRunWorkflowButtonMouseEnter,
|
|
2556
|
+
onMouseleave: onRunWorkflowButtonMouseLeave,
|
|
2557
|
+
onExecute: _cache[0] || (_cache[0] = ($event) => unref(runEntireWorkflow)("main")),
|
|
2558
|
+
onSelectTriggerNode: unref(workflowsStore).setSelectedTriggerNodeName
|
|
2559
|
+
}, null, 8, ["waiting-for-webhook", "disabled", "executing", "trigger-nodes", "get-node-type", "selected-trigger-node-name", "onSelectTriggerNode"])) : createCommentVNode("", true),
|
|
2560
|
+
containsChatTriggerNodes.value ? (openBlock(), createElementBlock(Fragment, { key: 1 }, [
|
|
2561
|
+
isLogsPanelOpen.value ? (openBlock(), createBlock(_sfc_main$1, {
|
|
2562
|
+
key: 0,
|
|
2563
|
+
type: "tertiary",
|
|
2564
|
+
label: unref(i18n).baseText("chat.hide"),
|
|
2565
|
+
class: normalizeClass(unref($style).chatButton),
|
|
2566
|
+
onClick: _cache[1] || (_cache[1] = ($event) => unref(logsStore).toggleOpen(false))
|
|
2567
|
+
}, null, 8, ["label", "class"])) : (openBlock(), createBlock(KeyboardShortcutTooltip, {
|
|
2568
|
+
key: 1,
|
|
2569
|
+
label: unref(i18n).baseText("chat.open"),
|
|
2570
|
+
shortcut: { keys: ["c"] }
|
|
2571
|
+
}, {
|
|
2572
|
+
default: withCtx(() => [
|
|
2573
|
+
createVNode(_sfc_main$1, {
|
|
2574
|
+
type: isRunWorkflowButtonVisible.value ? "secondary" : "primary",
|
|
2575
|
+
label: unref(i18n).baseText("chat.open"),
|
|
2576
|
+
class: normalizeClass(unref($style).chatButton),
|
|
2577
|
+
onClick: onOpenChat
|
|
2578
|
+
}, null, 8, ["type", "label", "class"])
|
|
2579
|
+
]),
|
|
2580
|
+
_: 1
|
|
2581
|
+
}, 8, ["label"]))
|
|
2582
|
+
], 64)) : createCommentVNode("", true),
|
|
2583
|
+
isStopExecutionButtonVisible.value ? (openBlock(), createBlock(_sfc_main$4, {
|
|
2584
|
+
key: 2,
|
|
2585
|
+
stopping: isStoppingExecution.value,
|
|
2586
|
+
onClick: onStopExecution
|
|
2587
|
+
}, null, 8, ["stopping"])) : createCommentVNode("", true),
|
|
2588
|
+
isStopWaitingForWebhookButtonVisible.value ? (openBlock(), createBlock(_sfc_main$3, {
|
|
2589
|
+
key: 3,
|
|
2590
|
+
onClick: onStopWaitingForWebhook
|
|
2591
|
+
})) : createCommentVNode("", true)
|
|
2592
|
+
], 2)) : createCommentVNode("", true),
|
|
2593
|
+
isReadOnlyEnvironment.value ? (openBlock(), createBlock(unref(N8nCallout), {
|
|
2594
|
+
key: 1,
|
|
2595
|
+
theme: "warning",
|
|
2596
|
+
icon: "lock",
|
|
2597
|
+
class: normalizeClass(unref($style).readOnlyEnvironmentNotification)
|
|
2598
|
+
}, {
|
|
2599
|
+
default: withCtx(() => [
|
|
2600
|
+
createTextVNode(toDisplayString(unref(i18n).baseText("readOnlyEnv.cantEditOrRun")), 1)
|
|
2601
|
+
]),
|
|
2602
|
+
_: 1
|
|
2603
|
+
}, 8, ["class"])) : createCommentVNode("", true),
|
|
2604
|
+
(openBlock(), createBlock(Suspense, null, {
|
|
2605
|
+
default: withCtx(() => [
|
|
2606
|
+
!isCanvasReadOnly.value ? (openBlock(), createBlock(unref(LazyNodeCreation), {
|
|
2607
|
+
key: 0,
|
|
2608
|
+
"create-node-active": unref(nodeCreatorStore).isCreateNodeActive,
|
|
2609
|
+
"node-view-scale": viewportTransform.value.zoom,
|
|
2610
|
+
onToggleNodeCreator,
|
|
2611
|
+
onAddNodes: onAddNodesAndConnections
|
|
2612
|
+
}, null, 8, ["create-node-active", "node-view-scale"])) : createCommentVNode("", true)
|
|
2613
|
+
]),
|
|
2614
|
+
_: 1
|
|
2615
|
+
})),
|
|
2616
|
+
(openBlock(), createBlock(Suspense, null, {
|
|
2617
|
+
default: withCtx(() => [
|
|
2618
|
+
!isNDVV2.value ? (openBlock(), createBlock(unref(LazyNodeDetailsView), {
|
|
2619
|
+
key: 0,
|
|
2620
|
+
"workflow-object": unref(editableWorkflowObject),
|
|
2621
|
+
"read-only": isCanvasReadOnly.value,
|
|
2622
|
+
"is-production-execution-preview": isProductionExecutionPreview.value,
|
|
2623
|
+
renaming: false,
|
|
2624
|
+
onValueChanged: _cache[2] || (_cache[2] = ($event) => onRenameNode($event.value)),
|
|
2625
|
+
onStopExecution,
|
|
2626
|
+
onSwitchSelectedNode: onSwitchActiveNode,
|
|
2627
|
+
onOpenConnectionNodeCreator: onOpenSelectiveNodeCreator,
|
|
2628
|
+
onSaveKeyboardShortcut: onSaveWorkflow
|
|
2629
|
+
}, null, 8, ["workflow-object", "read-only", "is-production-execution-preview"])) : createCommentVNode("", true)
|
|
2630
|
+
]),
|
|
2631
|
+
_: 1
|
|
2632
|
+
})),
|
|
2633
|
+
(openBlock(), createBlock(Suspense, null, {
|
|
2634
|
+
default: withCtx(() => [
|
|
2635
|
+
isNDVV2.value ? (openBlock(), createBlock(unref(LazyNodeDetailsViewV2), {
|
|
2636
|
+
key: 0,
|
|
2637
|
+
"workflow-object": unref(editableWorkflowObject),
|
|
2638
|
+
"read-only": isCanvasReadOnly.value,
|
|
2639
|
+
"is-production-execution-preview": isProductionExecutionPreview.value,
|
|
2640
|
+
onRenameNode,
|
|
2641
|
+
onStopExecution,
|
|
2642
|
+
onSwitchSelectedNode: onSwitchActiveNode,
|
|
2643
|
+
onOpenConnectionNodeCreator: onOpenSelectiveNodeCreator,
|
|
2644
|
+
onSaveKeyboardShortcut: onSaveWorkflow
|
|
2645
|
+
}, null, 8, ["workflow-object", "read-only", "is-production-execution-preview"])) : createCommentVNode("", true)
|
|
2646
|
+
]),
|
|
2647
|
+
_: 1
|
|
2648
|
+
}))
|
|
2649
|
+
]),
|
|
2650
|
+
_: 1
|
|
2651
|
+
}, 8, ["id", "workflow", "workflow-object", "fallback-nodes", "show-fallback-nodes", "event-bus", "read-only", "executing", "key-bindings", "onUpdate:logs:inputOpen", "onUpdate:logs:outputOpen", "onUpdate:hasRangeSelection"])) : createCommentVNode("", true),
|
|
2652
|
+
!isLoading.value ? (openBlock(), createBlock(FocusPanel, {
|
|
2653
|
+
key: 1,
|
|
2654
|
+
"is-canvas-read-only": isCanvasReadOnly.value,
|
|
2655
|
+
onSaveKeyboardShortcut: onSaveWorkflow
|
|
2656
|
+
}, null, 8, ["is-canvas-read-only"])) : createCommentVNode("", true)
|
|
2657
|
+
], 2);
|
|
2658
|
+
};
|
|
2659
|
+
}
|
|
2660
|
+
});
|
|
2661
|
+
const wrapper = "_wrapper_1xmhy_123";
|
|
2662
|
+
const executionButtons = "_executionButtons_1xmhy_128";
|
|
2663
|
+
const chatButton = "_chatButton_1xmhy_165";
|
|
2664
|
+
const setupCredentialsButtonWrapper = "_setupCredentialsButtonWrapper_1xmhy_169";
|
|
2665
|
+
const readOnlyEnvironmentNotification = "_readOnlyEnvironmentNotification_1xmhy_175";
|
|
2666
|
+
const style0 = {
|
|
2667
|
+
wrapper,
|
|
2668
|
+
executionButtons,
|
|
2669
|
+
chatButton,
|
|
2670
|
+
setupCredentialsButtonWrapper,
|
|
2671
|
+
readOnlyEnvironmentNotification
|
|
2672
|
+
};
|
|
2673
|
+
const cssModules = {
|
|
2674
|
+
"$style": style0
|
|
2675
|
+
};
|
|
2676
|
+
const NodeView = /* @__PURE__ */ _export_sfc(_sfc_main, [["__cssModules", cssModules]]);
|
|
2677
|
+
const NodeView$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2678
|
+
__proto__: null,
|
|
2679
|
+
default: NodeView
|
|
2680
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
2681
|
+
export {
|
|
2682
|
+
NodeView$1 as N,
|
|
2683
|
+
useExecutionData as u
|
|
2684
|
+
};
|