UNPKG

n8n-editor-ui

Version:

Workflow Editor UI for n8n

808 lines (807 loc) 34 kB
import { C as computed, Cn as toDisplayString, D as createElementBlock, E as createCommentVNode, Gt as unref, It as ref, J as onBeforeUnmount, M as createVNode, P as defineComponent, T as createBlock, Z as onMounted, _ as Fragment, _t as watch, bt as withCtx, et as openBlock, it as renderList, j as createTextVNode, ot as resolveComponent, r as TransitionGroup, vn as normalizeClass, w as createBaseVNode } from "./vue.runtime.esm-bundler-tP5dCd7J.js"; import { _t as useI18n } from "./_MapCache-ficiegRb.js"; import { Cn as N8nSpinner_default, Lt as ElCheckbox, at as N8nLoading_default, ht as N8nTooltip_default, ot as N8nActionDropdown_default, v as N8nTags_default, wn as N8nIcon_default, xn as N8nText_default, yn as N8nHeading_default } from "./src-DgvumQTi.js"; import "./en-CF30SCh2.js"; import "./preload-helper-CR0ecmWK.js"; import { t as __plugin_vue_export_helper_default } from "./_plugin-vue_export-helper-BwBpWJRZ.js"; import { _ as onBeforeRouteLeave, v as useRoute, y as useRouter } from "./truncate-B1HVeveJ.js"; import "./date-picker-B6nJ4qMb.js"; import { Et as executionRetryMessage, N as useWorkflowsStore, Nt as useNodeTypesStore, O as useTelemetry, Xn as useProjectsStore, Y as getNodeViewTab, gs as useSettingsStore, kr as isComponentPublicInstance, n as useWorkflowSaving, v as useToast } from "./builder.store-sBTWwxRU.js"; import "./empty-BuGRxzl4.js"; import "./sanitize-html-Cc45ZKm8.js"; import "./CalendarDate-zWqgZMlk.js"; import "./path-browserify-BtCDmZ3_.js"; import { Lo as MAIN_HEADER_TABS, Oo as getResourcePermissions, Ro as VIEWS, bc as EnterpriseEditionFeature } from "./constants-BbpucWL4.js"; import "./merge-k8vSyyXH.js"; import { o as NO_NETWORK_ERROR_CODE } from "./_baseOrderBy-B_6CV8x6.js"; import "./dateformat-CM9k0--B.js"; import { t as useDebounce } from "./useDebounce-Bnb8W2LR.js"; import { t as useExecutionsStore } from "./executions.store-CXjGPxs0.js"; import "./usePinnedData-CL2qWhwp.js"; import "./nodeCreator.store-FJrC_Pu6.js"; import "./nodeIcon-DI2Acud1.js"; import { t as useCanvasOperations } from "./useCanvasOperations-CAHezq7d.js"; import "./folders.store-BjAwtSH4.js"; import "./versions.store-BwdT833-.js"; import { t as usePageRedirectionHelper } from "./usePageRedirectionHelper-fGNB6ZKK.js"; import { a as toTime, i as toDayMonth } from "./dateFormatter-DDfPHI9I.js"; import { t as useExecutionHelpers } from "./useExecutionHelpers-BhJEW8lu.js"; import "./TagsDropdown-LwHy1RX4.js"; import "./WorkflowTagsDropdown-DEysJMrX.js"; import { t as WorkflowExecutionsInfoAccordion_default } from "./WorkflowExecutionsInfoAccordion-De8z4J-p.js"; import "./AnnotationTagsDropdown.ee-CF7otrg2.js"; import { i as ExecutionStopAllText_default, n as ExecutionsFilter_default, r as ConcurrentExecutionsHeader_default, t as ExecutionsTime_default } from "./ExecutionsTime-BLYKUkCX.js"; import { t as useIntersectionObserver } from "./useIntersectionObserver-DXKoRNFj.js"; var _hoisted_1$1 = { key: 2 }; var WorkflowExecutionsCard_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({ __name: "WorkflowExecutionsCard", props: { execution: {}, highlight: { type: Boolean }, showGap: { type: Boolean }, workflowPermissions: {} }, emits: ["retryExecution", "mounted"], setup(__props, { emit: __emit }) { const props = __props; const emit = __emit; const route = useRoute(); const locale = useI18n(); const executionHelpers = useExecutionHelpers(); const workflowsStore = useWorkflowsStore(); const settingsStore = useSettingsStore(); const isAdvancedExecutionFilterEnabled = computed(() => settingsStore.isEnterpriseFeatureEnabled[EnterpriseEditionFeature.AdvancedExecutionFilters]); const isAnnotationEnabled = computed(() => isAdvancedExecutionFilterEnabled.value); const currentWorkflow = computed(() => route.params.name || workflowsStore.workflowId); const retryExecutionActions = computed(() => [{ id: "current-workflow", label: locale.baseText("executionsList.retryWithCurrentlySavedWorkflow") }, { id: "original-workflow", label: locale.baseText("executionsList.retryWithOriginalWorkflow") }]); const executionUIDetails = computed(() => executionHelpers.getUIDetails(props.execution)); const isActive = computed(() => props.execution.id === route.params.executionId); const isRetriable = computed(() => executionHelpers.isExecutionRetriable(props.execution)); onMounted(() => { emit("mounted", props.execution.id); }); function onRetryMenuItemSelect(action) { emit("retryExecution", { execution: props.execution, command: action }); } return (_ctx, _cache) => { const _component_RouterLink = resolveComponent("RouterLink"); return openBlock(), createElementBlock("div", { class: normalizeClass({ ["execution-card"]: true, [_ctx.$style.WorkflowExecutionsCard]: true, [_ctx.$style.active]: isActive.value, [_ctx.$style[executionUIDetails.value.name]]: true, [_ctx.$style.highlight]: _ctx.highlight, [_ctx.$style.showGap]: _ctx.showGap }) }, [createVNode(_component_RouterLink, { class: normalizeClass(_ctx.$style.executionLink), to: { name: unref(VIEWS).EXECUTION_PREVIEW, params: { name: currentWorkflow.value, executionId: _ctx.execution.id }, query: unref(route).query }, "data-test-execution-status": executionUIDetails.value.name }, { default: withCtx(() => [createBaseVNode("div", { class: normalizeClass(_ctx.$style.description) }, [ executionUIDetails.value.name === "new" ? (openBlock(), createBlock(unref(N8nText_default), { key: 0, color: "text-dark", bold: true, size: "medium", "data-test-id": "execution-time" }, { default: withCtx(() => [createTextVNode(toDisplayString(unref(toDayMonth)(executionUIDetails.value.createdAt)) + " - " + toDisplayString(unref(locale).baseText("executionDetails.startingSoon")), 1)]), _: 1 })) : (openBlock(), createBlock(unref(N8nText_default), { key: 1, color: "text-dark", bold: true, size: "medium", "data-test-id": "execution-time" }, { default: withCtx(() => [createTextVNode(toDisplayString(executionUIDetails.value.startTime), 1)]), _: 1 })), createBaseVNode("div", { class: normalizeClass(_ctx.$style.executionStatus) }, [ executionUIDetails.value.name === "running" ? (openBlock(), createBlock(unref(N8nSpinner_default), { key: 0, size: "small", class: normalizeClass([_ctx.$style.spinner, "mr-4xs"]) }, null, 8, ["class"])) : createCommentVNode("", true), createVNode(unref(N8nText_default), { class: normalizeClass(_ctx.$style.statusLabel), size: "small" }, { default: withCtx(() => [createTextVNode(toDisplayString(executionUIDetails.value.label), 1)]), _: 1 }, 8, ["class"]), _cache[0] || (_cache[0] = createTextVNode(" " + toDisplayString(" ") + " ")), executionUIDetails.value.name === "running" && !_ctx.execution.stoppedAt ? (openBlock(), createBlock(unref(N8nText_default), { key: 1, color: isActive.value ? "text-dark" : "text-base", size: "small", "data-test-id": "execution-time-in-status" }, { default: withCtx(() => [createTextVNode(toDisplayString(unref(locale).baseText("executionDetails.runningTimeRunning")) + " ", 1), createVNode(ExecutionsTime_default, { "start-time": _ctx.execution.startedAt ?? _ctx.execution.createdAt }, null, 8, ["start-time"])]), _: 1 }, 8, ["color"])) : createCommentVNode("", true), executionUIDetails.value.name === "new" && _ctx.execution.createdAt ? (openBlock(), createBlock(unref(N8nText_default), { key: 2, color: isActive.value ? "text-dark" : "text-base", size: "small" }, { default: withCtx(() => [createBaseVNode("span", null, toDisplayString(unref(locale).baseText("executionDetails.at")) + " " + toDisplayString(unref(toTime)(_ctx.execution.createdAt)), 1)]), _: 1 }, 8, ["color"])) : executionUIDetails.value.runningTime !== "" ? (openBlock(), createBlock(unref(N8nText_default), { key: 3, color: isActive.value ? "text-dark" : "text-base", size: "small" }, { default: withCtx(() => [createTextVNode(toDisplayString(unref(locale).baseText("executionDetails.runningTimeFinished", { interpolate: { time: executionUIDetails.value?.runningTime } })), 1)]), _: 1 }, 8, ["color"])) : createCommentVNode("", true) ], 2), _ctx.execution.mode === "retry" ? (openBlock(), createElementBlock("div", _hoisted_1$1, [createVNode(unref(N8nText_default), { color: isActive.value ? "text-dark" : "text-base", size: "small" }, { default: withCtx(() => [createTextVNode(toDisplayString(unref(locale).baseText("executionDetails.retry")) + " #" + toDisplayString(_ctx.execution.retryOf), 1)]), _: 1 }, 8, ["color"])])) : createCommentVNode("", true), isAnnotationEnabled.value ? (openBlock(), createElementBlock("div", { key: 3, class: normalizeClass(_ctx.$style.annotation) }, [_ctx.execution.annotation?.vote ? (openBlock(), createElementBlock("div", { key: 0, class: normalizeClass(_ctx.$style.ratingIcon) }, [_ctx.execution.annotation.vote == "up" ? (openBlock(), createBlock(unref(N8nIcon_default), { key: 0, class: normalizeClass(_ctx.$style.up), icon: "thumbs-up" }, null, 8, ["class"])) : (openBlock(), createBlock(unref(N8nIcon_default), { key: 1, class: normalizeClass(_ctx.$style.down), icon: "thumbs-down" }, null, 8, ["class"]))], 2)) : createCommentVNode("", true), executionUIDetails.value.tags.length > 0 ? (openBlock(), createBlock(unref(N8nTags_default), { key: 1, tags: executionUIDetails.value.tags, clickable: false }, null, 8, ["tags"])) : createCommentVNode("", true)], 2)) : createCommentVNode("", true) ], 2), createBaseVNode("div", { class: normalizeClass(_ctx.$style.icons) }, [ isRetriable.value ? (openBlock(), createBlock(unref(N8nActionDropdown_default), { key: 0, class: normalizeClass([_ctx.$style.icon, _ctx.$style.retry]), items: retryExecutionActions.value, disabled: !_ctx.workflowPermissions.execute, "activator-icon": "redo-2", "data-test-id": "retry-execution-button", onSelect: onRetryMenuItemSelect }, null, 8, [ "class", "items", "disabled" ])) : createCommentVNode("", true), _ctx.execution.mode === "manual" ? (openBlock(), createBlock(unref(N8nTooltip_default), { key: 1, placement: "top" }, { content: withCtx(() => [createBaseVNode("span", null, toDisplayString(unref(locale).baseText("executionsList.test")), 1)]), default: withCtx(() => [createVNode(unref(N8nIcon_default), { class: normalizeClass([_ctx.$style.icon, _ctx.$style.manual]), icon: "flask-conical" }, null, 8, ["class"])]), _: 1 })) : createCommentVNode("", true), _ctx.execution.mode === "evaluation" ? (openBlock(), createBlock(unref(N8nTooltip_default), { key: 2, placement: "top" }, { content: withCtx(() => [createBaseVNode("span", null, toDisplayString(unref(locale).baseText("executionsList.evaluation")), 1)]), default: withCtx(() => [createVNode(unref(N8nIcon_default), { class: normalizeClass([_ctx.$style.icon, _ctx.$style.evaluation]), icon: "check-check" }, null, 8, ["class"])]), _: 1 })) : createCommentVNode("", true) ], 2)]), _: 1 }, 8, [ "class", "to", "data-test-execution-status" ])], 2); }; } }); const WorkflowExecutionsCard = "_WorkflowExecutionsCard_19371_123"; const active = "_active_19371_130"; const executionStatus = "_executionStatus_19371_133"; const executionLink = "_executionLink_19371_136"; const spinner = "_spinner_19371_139"; const running = "_running_19371_139"; const statusLabel = "_statusLabel_19371_146"; const success = "_success_19371_151"; const waiting = "_waiting_19371_160"; const error = "_error_19371_166"; const unknown = "_unknown_19371_172"; const annotation = "_annotation_19371_175"; const ratingIcon = "_ratingIcon_19371_182"; const up = "_up_19371_182"; const down = "_down_19371_185"; const icon = "_icon_19371_202"; const icons = "_icons_19371_207"; const retry = "_retry_19371_215"; const manual = "_manual_19371_218"; const showGap = "_showGap_19371_226"; var WorkflowExecutionsCard_vue_vue_type_style_index_0_lang_module_default = { WorkflowExecutionsCard, active, executionStatus, executionLink, "new": "_new_19371_139", spinner, running, statusLabel, success, waiting, error, unknown, annotation, ratingIcon, up, down, icon, icons, retry, manual, showGap }; var WorkflowExecutionsCard_default = /* @__PURE__ */ __plugin_vue_export_helper_default(WorkflowExecutionsCard_vue_vue_type_script_setup_true_lang_default, [["__cssModules", { "$style": WorkflowExecutionsCard_vue_vue_type_style_index_0_lang_module_default }]]); var _hoisted_1 = { key: 0, class: "mr-l" }; var _hoisted_2 = { key: 3, class: "mr-m" }; var WorkflowExecutionsSidebar_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({ __name: "WorkflowExecutionsSidebar", props: { workflow: {}, executions: {}, loading: { type: Boolean }, loadingMore: { type: Boolean }, temporaryExecution: {} }, emits: [ "retryExecution", "loadMore", "filterUpdated", "update:autoRefresh", "execution:stopMany" ], setup(__props, { emit: __emit }) { const props = __props; const emit = __emit; const route = useRoute(); const router = useRouter(); const i18n = useI18n(); const executionsStore = useExecutionsStore(); const settingsStore = useSettingsStore(); const pageRedirectionHelper = usePageRedirectionHelper(); const autoScrollDeps = ref({ activeExecutionSet: false, cardsMounted: false, scroll: true }); const currentWorkflowExecutionsCardRefs = ref({}); const executionListRef = ref(null); const { observe: observeForLoadMore } = useIntersectionObserver({ root: executionListRef, threshold: .01, onIntersect: () => emit("loadMore", 20) }); const workflowPermissions = computed(() => getResourcePermissions(props.workflow?.scopes).workflow); const showConcurrencyHeader = computed(() => settingsStore.isConcurrencyEnabled && !settingsStore.isQueueModeEnabled); watch(() => route, (to, from) => { if (from.name === VIEWS.EXECUTION_PREVIEW && to.name === VIEWS.EXECUTION_HOME) router.go(-1); }); watch(() => executionsStore.activeExecution, (newValue, oldValue) => { if (newValue && newValue.id !== oldValue?.id) autoScrollDeps.value.activeExecutionSet = true; }); watch(autoScrollDeps, (updatedDeps) => { if (Object.values(updatedDeps).every(Boolean)) scrollToActiveCard(); }, { deep: true }); function addCurrentWorkflowExecutionsCardRef(comp, id) { if (comp && isComponentPublicInstance(comp) && id) currentWorkflowExecutionsCardRefs.value[id] = comp; } function onItemMounted(id) { const index = props.executions.findIndex((execution) => execution.id === id); if (executionsStore.activeExecution?.id === id) { autoScrollDeps.value.activeExecutionSet = true; autoScrollDeps.value.cardsMounted = true; } if (index === props.executions.length - 1 && !props.loading && !props.loadingMore) { const cardElement = currentWorkflowExecutionsCardRefs.value[id]?.$el; observeForLoadMore(cardElement); } } function loadMore(limit = 20) { if (!props.loading) { if (executionListRef.value) { const diff = executionListRef.value.offsetHeight - (executionListRef.value.scrollHeight - executionListRef.value.scrollTop); if (diff > -10 && diff < 10) emit("loadMore", limit); } } } function onRetryExecution(payload) { emit("retryExecution", payload); } function onFilterChanged(filter) { autoScrollDeps.value.activeExecutionSet = false; autoScrollDeps.value.cardsMounted = false; autoScrollDeps.value.scroll = true; emit("filterUpdated", filter); } function onAutoRefreshChange(enabled) { emit("update:autoRefresh", typeof enabled === "boolean" ? enabled : Boolean(enabled)); } function scrollToActiveCard() { if (executionListRef.value && executionsStore.activeExecution && currentWorkflowExecutionsCardRefs.value[executionsStore.activeExecution.id]) { const cardRect = currentWorkflowExecutionsCardRefs.value[executionsStore.activeExecution.id].$el.getBoundingClientRect(); const LIST_HEADER_OFFSET = 200; if (cardRect.top > executionListRef.value.offsetHeight) { autoScrollDeps.value.scroll = false; executionListRef.value.scrollTo({ top: cardRect.top - LIST_HEADER_OFFSET, behavior: "smooth" }); } } } const goToUpgrade = () => { pageRedirectionHelper.goToUpgrade("concurrency", "upgrade-concurrency"); }; return (_ctx, _cache) => { return openBlock(), createElementBlock("div", { class: normalizeClass(["executions-sidebar", _ctx.$style.container]), "data-test-id": "executions-sidebar" }, [ createBaseVNode("div", { class: normalizeClass(_ctx.$style.heading) }, [ createVNode(unref(N8nHeading_default), { tag: "h2", size: "medium", color: "text-dark" }, { default: withCtx(() => [createTextVNode(toDisplayString(unref(i18n).baseText("generic.executions")), 1)]), _: 1 }), showConcurrencyHeader.value ? (openBlock(), createBlock(ConcurrentExecutionsHeader_default, { key: 0, "running-executions-count": unref(executionsStore).concurrentExecutionsCount, "concurrency-cap": unref(settingsStore).concurrency, "is-cloud-deployment": unref(settingsStore).isCloudDeployment, onGoToUpgrade: goToUpgrade }, null, 8, [ "running-executions-count", "concurrency-cap", "is-cloud-deployment" ])) : createCommentVNode("", true), createVNode(ExecutionStopAllText_default, { executions: props.executions }, null, 8, ["executions"]) ], 2), createBaseVNode("div", { class: normalizeClass(_ctx.$style.controls) }, [createVNode(unref(ElCheckbox), { modelValue: unref(executionsStore).autoRefresh, "onUpdate:modelValue": [_cache[0] || (_cache[0] = ($event) => unref(executionsStore).autoRefresh = $event), onAutoRefreshChange], "data-test-id": "auto-refresh-checkbox" }, { default: withCtx(() => [createTextVNode(toDisplayString(unref(i18n).baseText("executionsList.autoRefresh")), 1)]), _: 1 }, 8, ["modelValue"]), createVNode(ExecutionsFilter_default, { "popover-side": "right", "popover-align": "start", onFilterChanged })], 2), createBaseVNode("div", { ref_key: "executionListRef", ref: executionListRef, class: normalizeClass(_ctx.$style.executionList), "data-test-id": "current-executions-list", onScroll: _cache[1] || (_cache[1] = ($event) => loadMore(20)) }, [ _ctx.loading ? (openBlock(), createElementBlock("div", _hoisted_1, [createVNode(unref(N8nLoading_default), { variant: "rect" })])) : createCommentVNode("", true), !_ctx.loading && _ctx.executions.length === 0 ? (openBlock(), createElementBlock("div", { key: 1, class: normalizeClass(_ctx.$style.noResultsContainer), "data-test-id": "execution-list-empty" }, [createVNode(unref(N8nText_default), { color: "text-base", size: "medium", align: "center" }, { default: withCtx(() => [createTextVNode(toDisplayString(unref(i18n).baseText("executionsLandingPage.noResults")), 1)]), _: 1 })], 2)) : _ctx.temporaryExecution ? (openBlock(), createBlock(WorkflowExecutionsCard_default, { key: 2, ref: (el) => addCurrentWorkflowExecutionsCardRef(el, _ctx.temporaryExecution?.id), execution: _ctx.temporaryExecution, "data-test-id": `execution-details-${_ctx.temporaryExecution.id}`, "show-gap": true, "workflow-permissions": workflowPermissions.value, onRetryExecution }, null, 8, [ "execution", "data-test-id", "workflow-permissions" ])) : createCommentVNode("", true), createVNode(TransitionGroup, { name: "executions-list" }, { default: withCtx(() => [(openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.executions, (execution) => { return openBlock(), createBlock(WorkflowExecutionsCard_default, { key: execution.id, ref_for: true, ref: (el) => addCurrentWorkflowExecutionsCardRef(el, execution.id), execution, "workflow-permissions": workflowPermissions.value, "data-test-id": `execution-details-${execution.id}`, onRetryExecution, onMounted: onItemMounted }, null, 8, [ "execution", "workflow-permissions", "data-test-id" ]); }), 128))]), _: 1 }), _ctx.loadingMore ? (openBlock(), createElementBlock("div", _hoisted_2, [createVNode(unref(N8nLoading_default), { variant: "p", rows: 1 })])) : createCommentVNode("", true) ], 34), createBaseVNode("div", { class: normalizeClass(_ctx.$style.infoAccordion) }, [createVNode(WorkflowExecutionsInfoAccordion_default, { "initially-expanded": false })], 2) ], 2); }; } }); var WorkflowExecutionsSidebar_vue_vue_type_style_index_0_lang_module_default = { container: "_container_tglte_123", heading: "_heading_tglte_135", controls: "_controls_tglte_142", executionList: "_executionList_tglte_154", infoAccordion: "_infoAccordion_tglte_172", noResultsContainer: "_noResultsContainer_tglte_185" }; var WorkflowExecutionsSidebar_default = /* @__PURE__ */ __plugin_vue_export_helper_default(WorkflowExecutionsSidebar_vue_vue_type_script_setup_true_lang_default, [["__cssModules", { "$style": WorkflowExecutionsSidebar_vue_vue_type_style_index_0_lang_module_default }], ["__scopeId", "data-v-8885c645"]]); var WorkflowExecutionsList_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({ __name: "WorkflowExecutionsList", props: { loading: { type: Boolean, default: false }, workflow: {}, executions: { default: () => [] }, execution: {}, loadingMore: { type: Boolean, default: false } }, emits: [ "execution:delete", "execution:stop", "execution:retry", "update:auto-refresh", "update:filters", "load-more", "reload" ], setup(__props, { emit: __emit }) { const props = __props; const emit = __emit; const { promptSaveUnsavedWorkflowChanges } = useWorkflowSaving({ router: useRouter() }); const temporaryExecution = computed(() => props.executions.find((execution) => execution.id === props.execution?.id) ? void 0 : props.execution ?? void 0); const hidePreview = computed(() => { return props.loading || !props.execution && props.executions.length; }); const onDeleteCurrentExecution = () => { if (!props.execution?.id) return; emit("execution:delete", props.execution.id); }; const onStopExecution = () => { if (!props.execution?.id) return; emit("execution:stop", props.execution.id); }; const onRetryExecution = (payload) => { const loadWorkflow = payload.command === "current-workflow"; emit("execution:retry", { id: payload.execution.id, loadWorkflow }); }; onBeforeRouteLeave(async (to, _, next) => { if (getNodeViewTab(to) === MAIN_HEADER_TABS.WORKFLOW) { next(); return; } await promptSaveUnsavedWorkflowChanges(next); }); return (_ctx, _cache) => { const _component_RouterView = resolveComponent("RouterView"); return openBlock(), createElementBlock("div", { class: normalizeClass(_ctx.$style.container) }, [createVNode(WorkflowExecutionsSidebar_default, { executions: _ctx.executions, loading: _ctx.loading && !_ctx.executions.length, "loading-more": _ctx.loadingMore, "temporary-execution": temporaryExecution.value, workflow: _ctx.workflow, "onUpdate:autoRefresh": _cache[0] || (_cache[0] = ($event) => emit("update:auto-refresh", $event)), onReloadExecutions: _cache[1] || (_cache[1] = ($event) => emit("reload")), onFilterUpdated: _cache[2] || (_cache[2] = ($event) => emit("update:filters", $event)), onLoadMore: _cache[3] || (_cache[3] = ($event) => emit("load-more")), onRetryExecution }, null, 8, [ "executions", "loading", "loading-more", "temporary-execution", "workflow" ]), !hidePreview.value ? (openBlock(), createElementBlock("div", { key: 0, class: normalizeClass(_ctx.$style.content) }, [createVNode(_component_RouterView, { name: "executionPreview", execution: _ctx.execution, onDeleteCurrentExecution, onRetryExecution, onStopExecution }, null, 8, ["execution"])], 2)) : createCommentVNode("", true)], 2); }; } }); var WorkflowExecutionsList_vue_vue_type_style_index_0_lang_module_default = { container: "_container_udnba_123", content: "_content_udnba_129" }; var WorkflowExecutionsList_default = /* @__PURE__ */ __plugin_vue_export_helper_default(WorkflowExecutionsList_vue_vue_type_script_setup_true_lang_default, [["__cssModules", { "$style": WorkflowExecutionsList_vue_vue_type_style_index_0_lang_module_default }]]); var WorkflowExecutionsView_default = /* @__PURE__ */ defineComponent({ __name: "WorkflowExecutionsView", setup(__props) { const executionsStore = useExecutionsStore(); const workflowsStore = useWorkflowsStore(); const nodeTypesStore = useNodeTypesStore(); const projectsStore = useProjectsStore(); const i18n = useI18n(); const telemetry = useTelemetry(); const route = useRoute(); const router = useRouter(); const toast = useToast(); const { callDebounced } = useDebounce(); const { initializeWorkspace } = useCanvasOperations(); const loading = ref(false); const loadingMore = ref(false); const workflow = ref(); const workflowId = computed(() => { const name = route.params.name; return typeof name === "string" ? name : void 0; }); const executionId = computed(() => { const id = route.params.executionId; return typeof id === "string" ? id : void 0; }); const executions = computed(() => workflowId.value ? [...executionsStore.currentExecutionsByWorkflowId[workflowId.value] ?? [], ...executionsStore.executionsByWorkflowId[workflowId.value] ?? []] : []); const execution = computed(() => { return executions.value.find((e) => e.id === executionId.value) ?? currentExecution.value; }); const currentExecution = ref(); const isNewWorkflowRoute = computed(() => { return route.query.new === "true"; }); watch(() => workflowId.value, async () => { await fetchWorkflow(); }); watch(() => executionId.value, async () => { await fetchExecution(); }); onMounted(async () => { await Promise.all([nodeTypesStore.loadNodeTypesIfNotLoaded(), fetchWorkflow()]); if (workflowId.value) await Promise.all([executionsStore.initialize(workflowId.value), fetchExecution()]); await initializeRoute(); document.addEventListener("visibilitychange", onDocumentVisibilityChange); }); onBeforeUnmount(() => { executionsStore.reset(); document.removeEventListener("visibilitychange", onDocumentVisibilityChange); }); async function fetchExecution() { if (!executionId.value) return; try { currentExecution.value = await executionsStore.fetchExecution(executionId.value); executionsStore.activeExecution = currentExecution.value; } catch (error$1) { toast.showError(error$1, i18n.baseText("nodeView.showError.openExecution.title")); } if (!currentExecution.value) { toast.showMessage({ type: "error", title: i18n.baseText("openExecution.missingExeuctionId.title"), message: i18n.baseText("openExecution.missingExeuctionId.message") }); return; } } function onDocumentVisibilityChange() { if (document.visibilityState === "hidden") executionsStore.stopAutoRefreshInterval(); else executionsStore.startAutoRefreshInterval(workflowId.value); } async function initializeRoute() { if (route.name === VIEWS.EXECUTION_HOME && executions.value.length > 0 && workflow.value) await router.replace({ name: VIEWS.EXECUTION_PREVIEW, params: { name: workflow.value.id, executionId: executions.value[0].id }, query: route.query }).catch(() => {}); } async function fetchWorkflow() { if (isNewWorkflowRoute.value) { workflow.value = workflowsStore.workflow; return; } if (workflowId.value) if (!workflowsStore.workflowsById[workflowId.value]) { try { await workflowsStore.fetchActiveWorkflows(); await initializeWorkspace(await workflowsStore.fetchWorkflow(workflowId.value)); } catch (error$1) { toast.showError(error$1, i18n.baseText("nodeView.showError.openWorkflow.title")); } workflow.value = workflowsStore.getWorkflowById(workflowId.value); const workflowData = await workflowsStore.fetchWorkflow(workflow.value.id); await projectsStore.setProjectNavActiveIdByWorkflowHomeProject(workflowData.homeProject); } else workflow.value = workflowsStore.workflowsById[workflowId.value]; } async function onAutoRefreshToggle(value) { if (value) await executionsStore.startAutoRefreshInterval(workflowId.value); else executionsStore.stopAutoRefreshInterval(); } async function onRefreshData() { if (!workflowId.value) return; try { await executionsStore.fetchExecutions({ ...executionsStore.executionsFilters, workflowId: workflowId.value }); } catch (error$1) { if (error$1.errorCode === 999) toast.showMessage({ title: i18n.baseText("executionsList.showError.refreshData.title"), message: error$1.message, type: "error", duration: 3500 }, false); else toast.showError(error$1, i18n.baseText("executionsList.showError.refreshData.title")); } } async function onUpdateFilters(newFilters) { executionsStore.reset(); executionsStore.setFilters(newFilters); await executionsStore.initialize(workflowId.value); } async function onExecutionStop(id) { if (!id) return; try { await executionsStore.stopCurrentExecution(id); toast.showMessage({ title: i18n.baseText("executionsList.showMessage.stopExecution.title"), message: i18n.baseText("executionsList.showMessage.stopExecution.message", { interpolate: { activeExecutionId: id } }), type: "success" }); await onRefreshData(); } catch (error$1) { toast.showError(error$1, i18n.baseText("executionsList.showError.stopExecution.title")); } } async function onExecutionDelete(id) { if (!id) return; loading.value = true; try { const executionIndex = executions.value.findIndex((e) => e.id === id); const nextExecution = executions.value[executionIndex + 1] || executions.value[executionIndex - 1] || executions.value[0]; await executionsStore.deleteExecutions({ ids: [id] }); if (workflow.value) if (executions.value.length > 0) await router.replace({ name: VIEWS.EXECUTION_PREVIEW, params: { name: workflow.value.id, executionId: nextExecution.id } }).catch(() => {}); else await router.replace({ name: VIEWS.EXECUTION_HOME, params: { name: workflow.value.id } }); } catch (error$1) { loading.value = false; toast.showError(error$1, i18n.baseText("executionsList.showError.handleDeleteSelected.title")); return; } loading.value = false; toast.showMessage({ title: i18n.baseText("executionsList.showMessage.handleDeleteSelected.title"), type: "success" }); } async function onExecutionRetry(payload) { toast.showMessage({ title: i18n.baseText("executionDetails.runningMessage"), type: "info", duration: 2e3 }); await retryExecution(payload); await onRefreshData(); telemetry.track("User clicked retry execution button", { workflow_id: workflow.value?.id, execution_id: payload.id, retry_type: payload.loadWorkflow ? "current" : "original" }); } async function retryExecution(payload) { try { const retryMessage = executionRetryMessage((await executionsStore.retryExecution(payload.id, payload.loadWorkflow)).status); if (retryMessage) toast.showMessage(retryMessage); } catch (error$1) { toast.showError(error$1, i18n.baseText("executionsList.showError.retryExecution.title")); } } async function onLoadMore() { if (!loadingMore.value) await callDebounced(loadMore, { debounceTime: 1e3 }); } async function loadMore() { if (!!executionsStore.executionsFilters.status?.includes("running") || executions.value.length >= executionsStore.executionsCount) return; loadingMore.value = true; let lastId; if (executions.value.length !== 0) lastId = executions.value.slice(-1)[0].id; try { await executionsStore.fetchExecutions(executionsStore.executionsFilters, lastId); } catch (error$1) { loadingMore.value = false; toast.showError(error$1, i18n.baseText("executionsList.showError.loadMore.title")); return; } loadingMore.value = false; } return (_ctx, _cache) => { return workflow.value ? (openBlock(), createBlock(WorkflowExecutionsList_default, { key: 0, executions: executions.value, execution: execution.value, workflow: workflow.value, loading: loading.value, "loading-more": loadingMore.value, "onExecution:stop": onExecutionStop, "onExecution:delete": onExecutionDelete, "onExecution:retry": onExecutionRetry, "onUpdate:filters": onUpdateFilters, "onUpdate:autoRefresh": onAutoRefreshToggle, onLoadMore, onReload: onRefreshData }, null, 8, [ "executions", "execution", "workflow", "loading", "loading-more" ])) : createCommentVNode("", true); }; } }); export { WorkflowExecutionsView_default as default };