mirror of
https://github.com/n8n-io/n8n.git
synced 2025-01-23 10:32:17 -08:00
refactor(editor): Refactor workflowHelpers mixin to composable (no-changelog) (#8600)
This commit is contained in:
parent
a6211c9a5d
commit
510bf8905d
|
@ -4,7 +4,7 @@ import InputTriple from '@/components/InputTriple/InputTriple.vue';
|
|||
import ParameterInputFull from '@/components/ParameterInputFull.vue';
|
||||
import ParameterInputHint from '@/components/ParameterInputHint.vue';
|
||||
import ParameterIssues from '@/components/ParameterIssues.vue';
|
||||
import { resolveParameter } from '@/mixins/workflowHelpers';
|
||||
import { resolveParameter } from '@/composables/useWorkflowHelpers';
|
||||
import { isExpression } from '@/utils/expressions';
|
||||
import { isObject } from '@jsplumb/util';
|
||||
import type { AssignmentValue, INodeProperties } from 'n8n-workflow';
|
||||
|
|
|
@ -3,7 +3,7 @@ import { useNDVStore } from '@/stores/ndv.store';
|
|||
import { createTestingPinia } from '@pinia/testing';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { fireEvent, within } from '@testing-library/vue';
|
||||
import * as workflowHelpers from '@/mixins/workflowHelpers';
|
||||
import * as workflowHelpers from '@/composables/useWorkflowHelpers';
|
||||
import AssignmentCollection from '../AssignmentCollection.vue';
|
||||
import { createPinia, setActivePinia } from 'pinia';
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { isObject } from 'lodash-es';
|
||||
import type { AssignmentValue, IDataObject } from 'n8n-workflow';
|
||||
import { resolveParameter } from '@/mixins/workflowHelpers';
|
||||
import { resolveParameter } from '@/composables/useWorkflowHelpers';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
|
||||
export function nameFromExpression(expression: string): string {
|
||||
|
|
|
@ -63,7 +63,6 @@ import { python } from '@codemirror/lang-python';
|
|||
import type { CodeExecutionMode, CodeNodeEditorLanguage } from 'n8n-workflow';
|
||||
import { CODE_EXECUTION_MODES, CODE_LANGUAGES } from 'n8n-workflow';
|
||||
|
||||
import { workflowHelpers } from '@/mixins/workflowHelpers'; // for json field completions
|
||||
import { ASK_AI_EXPERIMENT, CODE_NODE_TYPE } from '@/constants';
|
||||
import { codeNodeEditorEventBus } from '@/event-bus';
|
||||
import { useRootStore } from '@/stores/n8nRoot.store';
|
||||
|
@ -83,7 +82,7 @@ export default defineComponent({
|
|||
components: {
|
||||
AskAI,
|
||||
},
|
||||
mixins: [linterExtension, completerExtension, workflowHelpers],
|
||||
mixins: [linterExtension, completerExtension],
|
||||
props: {
|
||||
aiButtonEnabled: {
|
||||
type: Boolean,
|
||||
|
|
|
@ -37,7 +37,6 @@ import { defineComponent } from 'vue';
|
|||
import { mapStores } from 'pinia';
|
||||
import type { IN8nPromptResponse } from '@/Interface';
|
||||
import { VALID_EMAIL_REGEX } from '@/constants';
|
||||
import { workflowHelpers } from '@/mixins/workflowHelpers';
|
||||
import Modal from '@/components/Modal.vue';
|
||||
import { useSettingsStore } from '@/stores/settings.store';
|
||||
import { useRootStore } from '@/stores/n8nRoot.store';
|
||||
|
@ -47,7 +46,6 @@ import { useToast } from '@/composables/useToast';
|
|||
export default defineComponent({
|
||||
name: 'ContactPromptModal',
|
||||
components: { Modal },
|
||||
mixins: [workflowHelpers],
|
||||
props: ['modalName'],
|
||||
setup() {
|
||||
return {
|
||||
|
|
|
@ -51,7 +51,6 @@
|
|||
import { defineComponent } from 'vue';
|
||||
import { mapStores } from 'pinia';
|
||||
import { MAX_WORKFLOW_NAME_LENGTH, PLACEHOLDER_EMPTY_WORKFLOW_ID } from '@/constants';
|
||||
import { workflowHelpers } from '@/mixins/workflowHelpers';
|
||||
import { useToast } from '@/composables/useToast';
|
||||
import TagsDropdown from '@/components/TagsDropdown.vue';
|
||||
import Modal from '@/components/Modal.vue';
|
||||
|
@ -63,15 +62,20 @@ import { getWorkflowPermissions } from '@/permissions';
|
|||
import { useUsersStore } from '@/stores/users.store';
|
||||
import { createEventBus } from 'n8n-design-system/utils';
|
||||
import { useCredentialsStore } from '@/stores/credentials.store';
|
||||
import { useWorkflowHelpers } from '@/composables/useWorkflowHelpers';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'DuplicateWorkflow',
|
||||
components: { TagsDropdown, Modal },
|
||||
mixins: [workflowHelpers],
|
||||
props: ['modalName', 'isActive', 'data'],
|
||||
setup() {
|
||||
const router = useRouter();
|
||||
const workflowHelpers = useWorkflowHelpers(router);
|
||||
|
||||
return {
|
||||
...useToast(),
|
||||
workflowHelpers,
|
||||
};
|
||||
},
|
||||
data() {
|
||||
|
@ -156,13 +160,13 @@ export default defineComponent({
|
|||
await this.workflowsStore.fetchWorkflow(this.data.id);
|
||||
workflowToUpdate = workflow;
|
||||
|
||||
this.removeForeignCredentialsFromWorkflow(
|
||||
this.workflowHelpers.removeForeignCredentialsFromWorkflow(
|
||||
workflowToUpdate,
|
||||
this.credentialsStore.allCredentials,
|
||||
);
|
||||
}
|
||||
|
||||
const saved = await this.saveAsNewWorkflow({
|
||||
const saved = await this.workflowHelpers.saveAsNewWorkflow({
|
||||
name,
|
||||
data: workflowToUpdate,
|
||||
tags: this.currentTagIds,
|
||||
|
|
|
@ -45,7 +45,8 @@ import { useWorkflowsStore } from '@/stores/workflows.store';
|
|||
import { PLACEHOLDER_EMPTY_WORKFLOW_ID, WORKFLOW_SETTINGS_MODAL_KEY } from '@/constants';
|
||||
import type { IWorkflowSettings } from 'n8n-workflow';
|
||||
import { deepCopy } from 'n8n-workflow';
|
||||
import { workflowHelpers } from '@/mixins/workflowHelpers';
|
||||
import { useWorkflowHelpers } from '@/composables/useWorkflowHelpers';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
interface IWorkflowSaveSettings {
|
||||
saveFailedExecutions: boolean;
|
||||
|
@ -55,13 +56,20 @@ interface IWorkflowSaveSettings {
|
|||
|
||||
export default defineComponent({
|
||||
name: 'ExecutionsInfoAccordion',
|
||||
mixins: [workflowHelpers],
|
||||
props: {
|
||||
initiallyExpanded: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
setup() {
|
||||
const router = useRouter();
|
||||
const workflowHelpers = useWorkflowHelpers(router);
|
||||
|
||||
return {
|
||||
workflowHelpers,
|
||||
};
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
defaultValues: {
|
||||
|
@ -211,7 +219,7 @@ export default defineComponent({
|
|||
} else if (this.$route.params.name && this.$route.params.name !== 'new') {
|
||||
currentId = this.$route.params.name;
|
||||
}
|
||||
const saved = await this.saveCurrentWorkflow({
|
||||
const saved = await this.workflowHelpers.saveCurrentWorkflow({
|
||||
id: currentId,
|
||||
name: this.workflowName,
|
||||
tags: this.currentWorkflowTagIds,
|
||||
|
|
|
@ -55,12 +55,11 @@ import { NodeHelpers } from 'n8n-workflow';
|
|||
import { useMessage } from '@/composables/useMessage';
|
||||
import { useToast } from '@/composables/useToast';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import type { Route } from 'vue-router';
|
||||
import { useRouter, type Route } from 'vue-router';
|
||||
import { executionHelpers } from '@/mixins/executionsHelpers';
|
||||
import { range as _range } from 'lodash-es';
|
||||
import { NO_NETWORK_ERROR_CODE } from '@/utils/apiUtils';
|
||||
import { getNodeViewTab } from '@/utils/canvasUtils';
|
||||
import { workflowHelpers } from '@/mixins/workflowHelpers';
|
||||
import { useWorkflowsStore } from '@/stores/workflows.store';
|
||||
import { useUIStore } from '@/stores/ui.store';
|
||||
import { useSettingsStore } from '@/stores/settings.store';
|
||||
|
@ -69,6 +68,7 @@ import { useTagsStore } from '@/stores/tags.store';
|
|||
import { executionFilterToQueryFilter } from '@/utils/executionUtils';
|
||||
import { useExternalHooks } from '@/composables/useExternalHooks';
|
||||
import { useDebounce } from '@/composables/useDebounce';
|
||||
import { useWorkflowHelpers } from '@/composables/useWorkflowHelpers';
|
||||
|
||||
// Number of execution pages that are fetched before temporary execution card is shown
|
||||
const MAX_LOADING_ATTEMPTS = 5;
|
||||
|
@ -80,13 +80,16 @@ export default defineComponent({
|
|||
components: {
|
||||
ExecutionsSidebar,
|
||||
},
|
||||
mixins: [executionHelpers, workflowHelpers],
|
||||
mixins: [executionHelpers],
|
||||
setup() {
|
||||
const externalHooks = useExternalHooks();
|
||||
const router = useRouter();
|
||||
const workflowHelpers = useWorkflowHelpers(router);
|
||||
const { callDebounced } = useDebounce();
|
||||
|
||||
return {
|
||||
externalHooks,
|
||||
workflowHelpers,
|
||||
callDebounced,
|
||||
...useToast(),
|
||||
...useMessage(),
|
||||
|
@ -168,7 +171,7 @@ export default defineComponent({
|
|||
);
|
||||
|
||||
if (confirmModal === MODAL_CONFIRM) {
|
||||
const saved = await this.saveCurrentWorkflow({}, false);
|
||||
const saved = await this.workflowHelpers.saveCurrentWorkflow({}, false);
|
||||
if (saved) {
|
||||
await this.settingsStore.fetchPromptsData();
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ import { EditorView, keymap } from '@codemirror/view';
|
|||
import { EditorState, Prec } from '@codemirror/state';
|
||||
import { history, redo, undo } from '@codemirror/commands';
|
||||
|
||||
import { workflowHelpers } from '@/mixins/workflowHelpers';
|
||||
import { expressionManager } from '@/mixins/expressionManager';
|
||||
import { completionManager } from '@/mixins/completionManager';
|
||||
import { expressionInputHandler } from '@/plugins/codemirror/inputHandlers/expression.inputHandler';
|
||||
|
@ -22,7 +21,7 @@ import type { IVariableItemSelected } from '@/Interface';
|
|||
|
||||
export default defineComponent({
|
||||
name: 'ExpressionEditorModalInput',
|
||||
mixins: [expressionManager, completionManager, workflowHelpers],
|
||||
mixins: [expressionManager, completionManager],
|
||||
props: {
|
||||
modelValue: {
|
||||
type: String,
|
||||
|
|
|
@ -4,7 +4,7 @@ import InputTriple from '@/components/InputTriple/InputTriple.vue';
|
|||
import ParameterInputFull from '@/components/ParameterInputFull.vue';
|
||||
import ParameterIssues from '@/components/ParameterIssues.vue';
|
||||
import { useI18n } from '@/composables/useI18n';
|
||||
import { resolveParameter } from '@/mixins/workflowHelpers';
|
||||
import { resolveParameter } from '@/composables/useWorkflowHelpers';
|
||||
import { DateTime } from 'luxon';
|
||||
import {
|
||||
FilterError,
|
||||
|
@ -240,7 +240,7 @@ const onBlur = (): void => {
|
|||
@operatorChange="onOperatorChange"
|
||||
></OperatorSelect>
|
||||
</template>
|
||||
<template #right="{ breakpoint }" v-if="!operator.singleValue">
|
||||
<template v-if="!operator.singleValue" #right="{ breakpoint }">
|
||||
<ParameterInputFull
|
||||
:key="rightParameter.type"
|
||||
display-options
|
||||
|
|
|
@ -21,7 +21,7 @@ import { useI18n } from '@/composables/useI18n';
|
|||
import { useDebounce } from '@/composables/useDebounce';
|
||||
import Condition from './Condition.vue';
|
||||
import CombinatorSelect from './CombinatorSelect.vue';
|
||||
import { resolveParameter } from '@/mixins/workflowHelpers';
|
||||
import { resolveParameter } from '@/composables/useWorkflowHelpers';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
|
||||
interface Props {
|
||||
|
|
|
@ -12,7 +12,6 @@ import { history, redo, undo } from '@codemirror/commands';
|
|||
import { acceptCompletion, autocompletion, completionStatus } from '@codemirror/autocomplete';
|
||||
|
||||
import { useNDVStore } from '@/stores/ndv.store';
|
||||
import { workflowHelpers } from '@/mixins/workflowHelpers';
|
||||
import { expressionManager } from '@/mixins/expressionManager';
|
||||
import { highlighter } from '@/plugins/codemirror/resolvableHighlighter';
|
||||
import { expressionInputHandler } from '@/plugins/codemirror/inputHandlers/expression.inputHandler';
|
||||
|
@ -25,7 +24,7 @@ const editableConf = new Compartment();
|
|||
|
||||
export default defineComponent({
|
||||
name: 'InlineExpressionEditorInput',
|
||||
mixins: [completionManager, expressionManager, workflowHelpers],
|
||||
mixins: [completionManager, expressionManager],
|
||||
props: {
|
||||
modelValue: {
|
||||
type: String,
|
||||
|
|
|
@ -174,7 +174,6 @@ import type {
|
|||
Workflow,
|
||||
} from 'n8n-workflow';
|
||||
import RunData from './RunData.vue';
|
||||
import { workflowHelpers } from '@/mixins/workflowHelpers';
|
||||
import NodeExecuteButton from './NodeExecuteButton.vue';
|
||||
import WireMeUp from './WireMeUp.vue';
|
||||
import {
|
||||
|
@ -186,13 +185,13 @@ import {
|
|||
import { useWorkflowsStore } from '@/stores/workflows.store';
|
||||
import { useNDVStore } from '@/stores/ndv.store';
|
||||
import { useNodeTypesStore } from '@/stores/nodeTypes.store';
|
||||
import { useUIStore } from '@/stores/ui.store';
|
||||
|
||||
type MappingMode = 'debugging' | 'mapping';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'InputPanel',
|
||||
components: { RunData, NodeExecuteButton, WireMeUp },
|
||||
mixins: [workflowHelpers],
|
||||
props: {
|
||||
currentNodeName: {
|
||||
type: String,
|
||||
|
@ -236,7 +235,7 @@ export default defineComponent({
|
|||
};
|
||||
},
|
||||
computed: {
|
||||
...mapStores(useNodeTypesStore, useNDVStore, useWorkflowsStore),
|
||||
...mapStores(useNodeTypesStore, useNDVStore, useWorkflowsStore, useUIStore),
|
||||
focusedMappableInput(): string {
|
||||
return this.ndvStore.focusedMappableInput;
|
||||
},
|
||||
|
|
|
@ -29,7 +29,6 @@ import {
|
|||
VIEWS,
|
||||
} from '@/constants';
|
||||
import type { INodeUi, ITabBarItem } from '@/Interface';
|
||||
import { workflowHelpers } from '@/mixins/workflowHelpers';
|
||||
import { useNDVStore } from '@/stores/ndv.store';
|
||||
import { useSourceControlStore } from '@/stores/sourceControl.store';
|
||||
import { useUIStore } from '@/stores/ui.store';
|
||||
|
@ -40,13 +39,11 @@ export default defineComponent({
|
|||
WorkflowDetails,
|
||||
TabBar,
|
||||
},
|
||||
mixins: [pushConnection, workflowHelpers],
|
||||
mixins: [pushConnection],
|
||||
setup(props, ctx) {
|
||||
return {
|
||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
||||
...pushConnection.setup?.(props, ctx),
|
||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
||||
...workflowHelpers.setup?.(props, ctx),
|
||||
};
|
||||
},
|
||||
data() {
|
||||
|
|
|
@ -158,7 +158,6 @@ import ShortenName from '@/components/ShortenName.vue';
|
|||
import TagsContainer from '@/components/TagsContainer.vue';
|
||||
import PushConnectionTracker from '@/components/PushConnectionTracker.vue';
|
||||
import WorkflowActivator from '@/components/WorkflowActivator.vue';
|
||||
import { workflowHelpers } from '@/mixins/workflowHelpers';
|
||||
import SaveButton from '@/components/SaveButton.vue';
|
||||
import TagsDropdown from '@/components/TagsDropdown.vue';
|
||||
import InlineTextEdit from '@/components/InlineTextEdit.vue';
|
||||
|
@ -185,6 +184,8 @@ import { createEventBus } from 'n8n-design-system/utils';
|
|||
import { nodeViewEventBus } from '@/event-bus';
|
||||
import { hasPermission } from '@/rbac/permissions';
|
||||
import { useCanvasStore } from '@/stores/canvas.store';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { useWorkflowHelpers } from '@/composables/useWorkflowHelpers';
|
||||
|
||||
const hasChanged = (prev: string[], curr: string[]) => {
|
||||
if (prev.length !== curr.length) {
|
||||
|
@ -208,7 +209,6 @@ export default defineComponent({
|
|||
BreakpointsObserver,
|
||||
CollaborationPane,
|
||||
},
|
||||
mixins: [workflowHelpers],
|
||||
props: {
|
||||
readOnly: {
|
||||
type: Boolean,
|
||||
|
@ -216,7 +216,11 @@ export default defineComponent({
|
|||
},
|
||||
},
|
||||
setup() {
|
||||
const router = useRouter();
|
||||
const workflowHelpers = useWorkflowHelpers(router);
|
||||
|
||||
return {
|
||||
workflowHelpers,
|
||||
...useTitleChange(),
|
||||
...useToast(),
|
||||
...useMessage(),
|
||||
|
@ -390,7 +394,7 @@ export default defineComponent({
|
|||
} else if (this.$route.params.name && this.$route.params.name !== 'new') {
|
||||
currentId = this.$route.params.name;
|
||||
}
|
||||
const saved = await this.saveCurrentWorkflow({
|
||||
const saved = await this.workflowHelpers.saveCurrentWorkflow({
|
||||
id: currentId,
|
||||
name: this.workflowName,
|
||||
tags: this.currentWorkflowTagIds,
|
||||
|
@ -443,7 +447,7 @@ export default defineComponent({
|
|||
}
|
||||
this.tagsSaving = true;
|
||||
|
||||
const saved = await this.saveCurrentWorkflow({ tags });
|
||||
const saved = await this.workflowHelpers.saveCurrentWorkflow({ tags });
|
||||
this.$telemetry.track('User edited workflow tags', {
|
||||
workflow_id: this.currentWorkflowId,
|
||||
new_tag_count: tags.length,
|
||||
|
@ -494,7 +498,7 @@ export default defineComponent({
|
|||
return;
|
||||
}
|
||||
|
||||
const saved = await this.saveCurrentWorkflow({ name });
|
||||
const saved = await this.workflowHelpers.saveCurrentWorkflow({ name });
|
||||
if (saved) {
|
||||
this.isNameEditEnabled = false;
|
||||
}
|
||||
|
@ -539,7 +543,7 @@ export default defineComponent({
|
|||
break;
|
||||
}
|
||||
case WORKFLOW_MENU_ACTIONS.DOWNLOAD: {
|
||||
const workflowData = await this.getWorkflowDataToSave();
|
||||
const workflowData = await this.workflowHelpers.getWorkflowDataToSave();
|
||||
const { tags, ...data } = workflowData;
|
||||
const exportData: IWorkflowToShare = {
|
||||
...data,
|
||||
|
|
|
@ -189,7 +189,6 @@ import {
|
|||
WAIT_TIME_UNLIMITED,
|
||||
} from '@/constants';
|
||||
import { nodeBase } from '@/mixins/nodeBase';
|
||||
import { workflowHelpers } from '@/mixins/workflowHelpers';
|
||||
import type {
|
||||
ConnectionTypes,
|
||||
IExecutionsSummary,
|
||||
|
@ -227,7 +226,7 @@ export default defineComponent({
|
|||
FontAwesomeIcon,
|
||||
NodeIcon,
|
||||
},
|
||||
mixins: [nodeBase, workflowHelpers],
|
||||
mixins: [nodeBase],
|
||||
props: {
|
||||
isProductionExecutionPreview: {
|
||||
type: Boolean,
|
||||
|
|
|
@ -146,7 +146,6 @@ import type {
|
|||
} from 'n8n-workflow';
|
||||
import { jsonParse, NodeHelpers, NodeConnectionType } from 'n8n-workflow';
|
||||
import type { IExecutionResponse, INodeUi, IUpdateInformation, TargetItem } from '@/Interface';
|
||||
import { workflowHelpers } from '@/mixins/workflowHelpers';
|
||||
|
||||
import NodeSettings from '@/components/NodeSettings.vue';
|
||||
import NDVDraggablePanels from './NDVDraggablePanels.vue';
|
||||
|
@ -174,6 +173,8 @@ import { useNodeHelpers } from '@/composables/useNodeHelpers';
|
|||
import { useMessage } from '@/composables/useMessage';
|
||||
import { useExternalHooks } from '@/composables/useExternalHooks';
|
||||
import { usePinnedData } from '@/composables/usePinnedData';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { useWorkflowHelpers } from '@/composables/useWorkflowHelpers';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'NodeDetailsView',
|
||||
|
@ -184,7 +185,7 @@ export default defineComponent({
|
|||
NDVDraggablePanels,
|
||||
TriggerPanel,
|
||||
},
|
||||
mixins: [workflowHelpers, workflowActivate],
|
||||
mixins: [workflowActivate],
|
||||
props: {
|
||||
readOnly: {
|
||||
type: Boolean,
|
||||
|
@ -203,11 +204,14 @@ export default defineComponent({
|
|||
const nodeHelpers = useNodeHelpers();
|
||||
const { activeNode } = storeToRefs(ndvStore);
|
||||
const pinnedData = usePinnedData(activeNode);
|
||||
const router = useRouter();
|
||||
const workflowHelpers = useWorkflowHelpers(router);
|
||||
|
||||
return {
|
||||
externalHooks,
|
||||
nodeHelpers,
|
||||
pinnedData,
|
||||
workflowHelpers,
|
||||
...useDeviceSupport(),
|
||||
...useMessage(),
|
||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
||||
|
@ -289,7 +293,7 @@ export default defineComponent({
|
|||
);
|
||||
},
|
||||
workflow(): Workflow {
|
||||
return this.getCurrentWorkflow();
|
||||
return this.workflowHelpers.getCurrentWorkflow();
|
||||
},
|
||||
hasOutputConnection() {
|
||||
if (!this.activeNode) return false;
|
||||
|
@ -482,7 +486,7 @@ export default defineComponent({
|
|||
nodeSubtitle: this.nodeHelpers.getNodeSubtitle(
|
||||
node,
|
||||
this.activeNodeType,
|
||||
this.getCurrentWorkflow(),
|
||||
this.workflowHelpers.getCurrentWorkflow(),
|
||||
),
|
||||
});
|
||||
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
:size="size"
|
||||
:icon="!isListeningForEvents && 'flask'"
|
||||
:transparent-background="transparent"
|
||||
@click="onClick"
|
||||
:title="!isTriggerNode ? $locale.baseText('ndv.execute.testNode.description') : ''"
|
||||
@click="onClick"
|
||||
/>
|
||||
</div>
|
||||
</n8n-tooltip>
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
<div v-if="isWebhookMethodVisible(webhook)" class="webhook-wrapper">
|
||||
<div class="http-field">
|
||||
<div class="http-method">
|
||||
{{ getWebhookExpressionValue(webhook, 'httpMethod') }}<br />
|
||||
{{ workflowHelpers.getWebhookExpressionValue(webhook, 'httpMethod') }}<br />
|
||||
</div>
|
||||
</div>
|
||||
<div class="url-field">
|
||||
|
@ -62,21 +62,23 @@ import {
|
|||
OPEN_URL_PANEL_TRIGGER_NODE_TYPES,
|
||||
PRODUCTION_ONLY_TRIGGER_NODE_TYPES,
|
||||
} from '@/constants';
|
||||
import { workflowHelpers } from '@/mixins/workflowHelpers';
|
||||
import { useClipboard } from '@/composables/useClipboard';
|
||||
import { useWorkflowHelpers } from '@/composables/useWorkflowHelpers';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'NodeWebhooks',
|
||||
mixins: [workflowHelpers],
|
||||
props: [
|
||||
'node', // NodeUi
|
||||
'nodeType', // INodeTypeDescription
|
||||
],
|
||||
setup() {
|
||||
const router = useRouter();
|
||||
const clipboard = useClipboard();
|
||||
|
||||
const workflowHelpers = useWorkflowHelpers(router);
|
||||
return {
|
||||
clipboard,
|
||||
workflowHelpers,
|
||||
...useToast(),
|
||||
};
|
||||
},
|
||||
|
@ -102,7 +104,7 @@ export default defineComponent({
|
|||
visibleWebhookUrls(): IWebhookDescription[] {
|
||||
return this.webhooksNode.filter((webhook) => {
|
||||
if (typeof webhook.ndvHideUrl === 'string') {
|
||||
return !this.getWebhookExpressionValue(webhook, 'ndvHideUrl');
|
||||
return !this.workflowHelpers.getWebhookExpressionValue(webhook, 'ndvHideUrl');
|
||||
}
|
||||
|
||||
return !webhook.ndvHideUrl;
|
||||
|
@ -184,7 +186,7 @@ export default defineComponent({
|
|||
},
|
||||
getWebhookUrlDisplay(webhookData: IWebhookDescription): string {
|
||||
if (this.node) {
|
||||
return this.getWebhookUrl(
|
||||
return this.workflowHelpers.getWebhookUrl(
|
||||
webhookData,
|
||||
this.node,
|
||||
this.isProductionOnly ? 'production' : this.showUrlFor,
|
||||
|
@ -194,7 +196,7 @@ export default defineComponent({
|
|||
},
|
||||
isWebhookMethodVisible(webhook: IWebhookDescription): boolean {
|
||||
if (typeof webhook.ndvHideMethod === 'string') {
|
||||
return !this.getWebhookExpressionValue(webhook, 'ndvHideMethod');
|
||||
return !this.workflowHelpers.getWebhookExpressionValue(webhook, 'ndvHideMethod');
|
||||
}
|
||||
|
||||
return !webhook.ndvHideMethod;
|
||||
|
|
|
@ -502,7 +502,6 @@ import JsEditor from '@/components/JsEditor/JsEditor.vue';
|
|||
import JsonEditor from '@/components/JsonEditor/JsonEditor.vue';
|
||||
import SqlEditor from '@/components/SqlEditor/SqlEditor.vue';
|
||||
|
||||
import { workflowHelpers } from '@/mixins/workflowHelpers';
|
||||
import { hasExpressionMapping, isValueExpression } from '@/utils/nodeTypesUtils';
|
||||
import { isResourceLocatorValue } from '@/utils/typeGuards';
|
||||
|
||||
|
@ -523,6 +522,8 @@ import type { N8nInput } from 'n8n-design-system';
|
|||
import { isCredentialOnlyNodeType } from '@/utils/credentialOnlyNodes';
|
||||
import { useExternalHooks } from '@/composables/useExternalHooks';
|
||||
import { useDebounce } from '@/composables/useDebounce';
|
||||
import { useWorkflowHelpers } from '@/composables/useWorkflowHelpers';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
type Picker = { $emit: (arg0: string, arg1: Date) => void };
|
||||
|
||||
|
@ -541,7 +542,6 @@ export default defineComponent({
|
|||
ResourceLocator,
|
||||
TextEdit,
|
||||
},
|
||||
mixins: [workflowHelpers],
|
||||
props: {
|
||||
additionalExpressionData: {
|
||||
type: Object as PropType<IDataObject>,
|
||||
|
@ -618,11 +618,14 @@ export default defineComponent({
|
|||
const i18n = useI18n();
|
||||
const nodeHelpers = useNodeHelpers();
|
||||
const { callDebounced } = useDebounce();
|
||||
const router = useRouter();
|
||||
const workflowHelpers = useWorkflowHelpers(router);
|
||||
|
||||
return {
|
||||
externalHooks,
|
||||
i18n,
|
||||
nodeHelpers,
|
||||
workflowHelpers,
|
||||
callDebounced,
|
||||
};
|
||||
},
|
||||
|
@ -724,7 +727,7 @@ export default defineComponent({
|
|||
// Get the resolved parameter values of the current node
|
||||
const currentNodeParameters = this.ndvStore.activeNode?.parameters;
|
||||
try {
|
||||
const resolvedNodeParameters = this.resolveParameter(currentNodeParameters);
|
||||
const resolvedNodeParameters = this.workflowHelpers.resolveParameter(currentNodeParameters);
|
||||
|
||||
const returnValues: string[] = [];
|
||||
for (const parameterPath of loadOptionsDependsOn) {
|
||||
|
@ -969,7 +972,7 @@ export default defineComponent({
|
|||
return shortPath.join('.');
|
||||
},
|
||||
workflow(): Workflow {
|
||||
return this.getCurrentWorkflow();
|
||||
return this.workflowHelpers.getCurrentWorkflow();
|
||||
},
|
||||
isResourceLocatorParameter(): boolean {
|
||||
return this.parameter.type === 'resourceLocator';
|
||||
|
@ -1092,7 +1095,7 @@ export default defineComponent({
|
|||
|
||||
try {
|
||||
const currentNodeParameters = (this.ndvStore.activeNode as INodeUi).parameters;
|
||||
const resolvedNodeParameters = this.resolveRequiredParameters(
|
||||
const resolvedNodeParameters = this.workflowHelpers.resolveRequiredParameters(
|
||||
this.parameter,
|
||||
currentNodeParameters,
|
||||
) as INodeParameters;
|
||||
|
|
|
@ -182,7 +182,6 @@ import ResourceMapper from '@/components/ResourceMapper/ResourceMapper.vue';
|
|||
import FilterConditions from '@/components/FilterConditions/FilterConditions.vue';
|
||||
import AssignmentCollection from '@/components/AssignmentCollection/AssignmentCollection.vue';
|
||||
import { KEEP_AUTH_IN_NDV_FOR_NODES } from '@/constants';
|
||||
import { workflowHelpers } from '@/mixins/workflowHelpers';
|
||||
import { useNDVStore } from '@/stores/ndv.store';
|
||||
import { useNodeTypesStore } from '@/stores/nodeTypes.store';
|
||||
import {
|
||||
|
@ -192,6 +191,8 @@ import {
|
|||
} from '@/utils/nodeTypesUtils';
|
||||
import { get, set } from 'lodash-es';
|
||||
import { useNodeHelpers } from '@/composables/useNodeHelpers';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { useWorkflowHelpers } from '@/composables/useWorkflowHelpers';
|
||||
|
||||
const FixedCollectionParameter = defineAsyncComponent(
|
||||
async () => await import('./FixedCollectionParameter.vue'),
|
||||
|
@ -212,7 +213,6 @@ export default defineComponent({
|
|||
FilterConditions,
|
||||
AssignmentCollection,
|
||||
},
|
||||
mixins: [workflowHelpers],
|
||||
props: {
|
||||
nodeValues: {
|
||||
type: Object as PropType<INodeParameters>,
|
||||
|
@ -250,6 +250,8 @@ export default defineComponent({
|
|||
setup() {
|
||||
const nodeHelpers = useNodeHelpers();
|
||||
const asyncLoadingError = ref(false);
|
||||
const router = useRouter();
|
||||
const workflowHelpers = useWorkflowHelpers(router);
|
||||
|
||||
// This will catch errors in async components
|
||||
onErrorCaptured((e, component) => {
|
||||
|
@ -274,6 +276,7 @@ export default defineComponent({
|
|||
return {
|
||||
nodeHelpers,
|
||||
asyncLoadingError,
|
||||
workflowHelpers,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
@ -482,7 +485,7 @@ export default defineComponent({
|
|||
} else {
|
||||
// Contains probably no expression with a missing parameter so resolve
|
||||
try {
|
||||
nodeValues[key] = this.resolveExpression(
|
||||
nodeValues[key] = this.workflowHelpers.resolveExpression(
|
||||
rawValues[key],
|
||||
nodeValues,
|
||||
) as NodeParameterValue;
|
||||
|
@ -559,7 +562,7 @@ export default defineComponent({
|
|||
// Get the resolved parameter values of the current node
|
||||
const currentNodeParameters = this.ndvStore.activeNode?.parameters;
|
||||
try {
|
||||
const resolvedNodeParameters = this.resolveParameter(currentNodeParameters);
|
||||
const resolvedNodeParameters = this.workflowHelpers.resolveParameter(currentNodeParameters);
|
||||
|
||||
const returnValues: string[] = [];
|
||||
for (const parameterPath of loadOptionsDependsOn) {
|
||||
|
|
|
@ -53,7 +53,6 @@ import { defineComponent } from 'vue';
|
|||
import type { INodeUi, IUpdateInformation, TargetItem } from '@/Interface';
|
||||
import ParameterInput from '@/components/ParameterInput.vue';
|
||||
import InputHint from '@/components/ParameterInputHint.vue';
|
||||
import { workflowHelpers } from '@/mixins/workflowHelpers';
|
||||
import { useEnvironmentsStore } from '@/stores/environments.ee.store';
|
||||
import { useExternalSecretsStore } from '@/stores/externalSecrets.ee.store';
|
||||
import { useNDVStore } from '@/stores/ndv.store';
|
||||
|
@ -71,6 +70,8 @@ import { isResourceLocatorValue } from 'n8n-workflow';
|
|||
import { get } from 'lodash-es';
|
||||
import type { EventBus } from 'n8n-design-system/utils';
|
||||
import { createEventBus } from 'n8n-design-system/utils';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { useWorkflowHelpers } from '@/composables/useWorkflowHelpers';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'ParameterInputWrapper',
|
||||
|
@ -78,7 +79,6 @@ export default defineComponent({
|
|||
ParameterInput,
|
||||
InputHint,
|
||||
},
|
||||
mixins: [workflowHelpers],
|
||||
props: {
|
||||
additionalExpressionData: {
|
||||
type: Object as PropType<IDataObject>,
|
||||
|
@ -149,6 +149,14 @@ export default defineComponent({
|
|||
default: () => createEventBus(),
|
||||
},
|
||||
},
|
||||
setup() {
|
||||
const router = useRouter();
|
||||
const workflowHelpers = useWorkflowHelpers(router);
|
||||
|
||||
return {
|
||||
workflowHelpers,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapStores(useNDVStore, useExternalSecretsStore, useEnvironmentsStore),
|
||||
isValueExpression() {
|
||||
|
@ -209,7 +217,7 @@ export default defineComponent({
|
|||
};
|
||||
}
|
||||
|
||||
return { ok: true, result: this.resolveExpression(value, undefined, opts) };
|
||||
return { ok: true, result: this.workflowHelpers.resolveExpression(value, undefined, opts) };
|
||||
} catch (error) {
|
||||
return { ok: false, error };
|
||||
}
|
||||
|
|
|
@ -139,7 +139,6 @@ import {
|
|||
REPORTED_SOURCE_OTHER_KEY,
|
||||
VIEWS,
|
||||
} from '@/constants';
|
||||
import { workflowHelpers } from '@/mixins/workflowHelpers';
|
||||
import { useToast } from '@/composables/useToast';
|
||||
import Modal from '@/components/Modal.vue';
|
||||
import type { IFormInputs, IPersonalizationLatestVersion, IUser } from '@/Interface';
|
||||
|
@ -160,7 +159,6 @@ const SURVEY_VERSION = 'v4';
|
|||
export default defineComponent({
|
||||
name: 'PersonalizationModal',
|
||||
components: { Modal },
|
||||
mixins: [workflowHelpers],
|
||||
props: {
|
||||
teleported: {
|
||||
type: Boolean,
|
||||
|
|
|
@ -148,7 +148,6 @@ import type { IResourceLocatorReqParams, IResourceLocatorResultExpanded } from '
|
|||
import DraggableTarget from '@/components/DraggableTarget.vue';
|
||||
import ExpressionParameterInput from '@/components/ExpressionParameterInput.vue';
|
||||
import ParameterIssues from '@/components/ParameterIssues.vue';
|
||||
import { workflowHelpers } from '@/mixins/workflowHelpers';
|
||||
import { useRootStore } from '@/stores/n8nRoot.store';
|
||||
import { useNDVStore } from '@/stores/ndv.store';
|
||||
import { useNodeTypesStore } from '@/stores/nodeTypes.store';
|
||||
|
@ -174,6 +173,8 @@ import type { PropType } from 'vue';
|
|||
import { defineComponent } from 'vue';
|
||||
import ResourceLocatorDropdown from './ResourceLocatorDropdown.vue';
|
||||
import { useDebounce } from '@/composables/useDebounce';
|
||||
import { useWorkflowHelpers } from '@/composables/useWorkflowHelpers';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
interface IResourceLocatorQuery {
|
||||
results: INodeListSearchItems[];
|
||||
|
@ -190,7 +191,6 @@ export default defineComponent({
|
|||
ParameterIssues,
|
||||
ResourceLocatorDropdown,
|
||||
},
|
||||
mixins: [workflowHelpers],
|
||||
props: {
|
||||
parameter: {
|
||||
type: Object as PropType<INodeProperties>,
|
||||
|
@ -257,6 +257,14 @@ export default defineComponent({
|
|||
default: () => createEventBus(),
|
||||
},
|
||||
},
|
||||
setup() {
|
||||
const router = useRouter();
|
||||
const workflowHelpers = useWorkflowHelpers(router);
|
||||
|
||||
const { callDebounced } = useDebounce();
|
||||
|
||||
return { callDebounced, workflowHelpers };
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
resourceDropdownVisible: false,
|
||||
|
@ -267,11 +275,6 @@ export default defineComponent({
|
|||
width: 0,
|
||||
};
|
||||
},
|
||||
setup() {
|
||||
const { callDebounced } = useDebounce();
|
||||
|
||||
return { callDebounced };
|
||||
},
|
||||
computed: {
|
||||
...mapStores(useNodeTypesStore, useNDVStore, useRootStore, useUIStore, useWorkflowsStore),
|
||||
appName(): string {
|
||||
|
@ -370,7 +373,7 @@ export default defineComponent({
|
|||
const value = this.isValueExpression ? this.expressionComputedValue : this.valueToDisplay;
|
||||
if (typeof value === 'string') {
|
||||
const expression = this.currentMode.url.replace(/\{\{\$value\}\}/g, value);
|
||||
const resolved = this.resolveExpression(expression);
|
||||
const resolved = this.workflowHelpers.resolveExpression(expression);
|
||||
|
||||
return typeof resolved === 'string' ? resolved : null;
|
||||
}
|
||||
|
@ -683,7 +686,7 @@ export default defineComponent({
|
|||
});
|
||||
}
|
||||
|
||||
const resolvedNodeParameters = this.resolveRequiredParameters(
|
||||
const resolvedNodeParameters = this.workflowHelpers.resolveRequiredParameters(
|
||||
this.parameter,
|
||||
params.parameters,
|
||||
) as INodeParameters;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import type { IUpdateInformation, ResourceMapperReqParams } from '@/Interface';
|
||||
import { resolveRequiredParameters } from '@/mixins/workflowHelpers';
|
||||
import { resolveRequiredParameters } from '@/composables/useWorkflowHelpers';
|
||||
import { useNodeTypesStore } from '@/stores/nodeTypes.store';
|
||||
import type {
|
||||
INode,
|
||||
|
|
|
@ -106,7 +106,6 @@ import { defineComponent, ref } from 'vue';
|
|||
import { mapStores } from 'pinia';
|
||||
|
||||
import { nodeBase } from '@/mixins/nodeBase';
|
||||
import { workflowHelpers } from '@/mixins/workflowHelpers';
|
||||
import { isNumber, isString } from '@/utils/typeGuards';
|
||||
import type {
|
||||
INodeUi,
|
||||
|
@ -126,7 +125,7 @@ import { useDeviceSupport } from 'n8n-design-system';
|
|||
|
||||
export default defineComponent({
|
||||
name: 'Sticky',
|
||||
mixins: [nodeBase, workflowHelpers],
|
||||
mixins: [nodeBase],
|
||||
props: {
|
||||
nodeViewScale: {
|
||||
type: Number,
|
||||
|
@ -320,7 +319,7 @@ export default defineComponent({
|
|||
this.workflowsStore.updateNodeProperties(updateInformation);
|
||||
},
|
||||
touchStart() {
|
||||
if (this.deviceSupport.isTouchDevice === true && !this.isMacOs && !this.isTouchActive) {
|
||||
if (this.deviceSupport.isTouchDevice && !this.isMacOs && !this.isTouchActive) {
|
||||
this.isTouchActive = true;
|
||||
setTimeout(() => {
|
||||
this.isTouchActive = false;
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
</n8n-text>
|
||||
</div>
|
||||
<div v-if="displayChatButton">
|
||||
<n8n-button @click="openWebhookUrl()" class="mb-xl">
|
||||
<n8n-button class="mb-xl" @click="openWebhookUrl()">
|
||||
{{ $locale.baseText('ndv.trigger.chatTrigger.openChat') }}
|
||||
</n8n-button>
|
||||
</div>
|
||||
|
@ -121,7 +121,6 @@ import type { INodeUi } from '@/Interface';
|
|||
import type { INodeTypeDescription } from 'n8n-workflow';
|
||||
import { getTriggerNodeServiceName } from '@/utils/nodeTypesUtils';
|
||||
import NodeExecuteButton from '@/components/NodeExecuteButton.vue';
|
||||
import { workflowHelpers } from '@/mixins/workflowHelpers';
|
||||
import CopyInput from '@/components/CopyInput.vue';
|
||||
import NodeIcon from '@/components/NodeIcon.vue';
|
||||
import { useUIStore } from '@/stores/ui.store';
|
||||
|
@ -129,6 +128,8 @@ import { useWorkflowsStore } from '@/stores/workflows.store';
|
|||
import { useNDVStore } from '@/stores/ndv.store';
|
||||
import { useNodeTypesStore } from '@/stores/nodeTypes.store';
|
||||
import { createEventBus } from 'n8n-design-system/utils';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { useWorkflowHelpers } from '@/composables/useWorkflowHelpers';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'TriggerPanel',
|
||||
|
@ -137,7 +138,6 @@ export default defineComponent({
|
|||
CopyInput,
|
||||
NodeIcon,
|
||||
},
|
||||
mixins: [workflowHelpers],
|
||||
props: {
|
||||
nodeName: {
|
||||
type: String,
|
||||
|
@ -146,6 +146,14 @@ export default defineComponent({
|
|||
type: String,
|
||||
},
|
||||
},
|
||||
setup() {
|
||||
const router = useRouter();
|
||||
const workflowHelpers = useWorkflowHelpers(router);
|
||||
|
||||
return {
|
||||
workflowHelpers,
|
||||
};
|
||||
},
|
||||
data: () => {
|
||||
return {
|
||||
executionsHelpEventBus: createEventBus(),
|
||||
|
@ -178,12 +186,9 @@ export default defineComponent({
|
|||
}
|
||||
|
||||
if (this.node) {
|
||||
const hideContentValue = this.getCurrentWorkflow().expression.getSimpleParameterValue(
|
||||
this.node,
|
||||
hideContent,
|
||||
'internal',
|
||||
{},
|
||||
);
|
||||
const hideContentValue = this.workflowHelpers
|
||||
.getCurrentWorkflow()
|
||||
.expression.getSimpleParameterValue(this.node, hideContent, 'internal', {});
|
||||
|
||||
if (typeof hideContentValue === 'boolean') {
|
||||
return hideContentValue;
|
||||
|
@ -220,14 +225,17 @@ export default defineComponent({
|
|||
return undefined;
|
||||
}
|
||||
|
||||
return this.getWebhookExpressionValue(this.nodeType.webhooks[0], 'httpMethod');
|
||||
return this.workflowHelpers.getWebhookExpressionValue(
|
||||
this.nodeType.webhooks[0],
|
||||
'httpMethod',
|
||||
);
|
||||
},
|
||||
webhookTestUrl(): string | undefined {
|
||||
if (!this.node || !this.nodeType?.webhooks?.length) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return this.getWebhookUrl(this.nodeType.webhooks[0], this.node, 'test');
|
||||
return this.workflowHelpers.getWebhookUrl(this.nodeType.webhooks[0], this.node, 'test');
|
||||
},
|
||||
isWebhookBasedNode(): boolean {
|
||||
return Boolean(this.nodeType?.webhooks?.length);
|
||||
|
|
|
@ -62,7 +62,6 @@ import type { IN8nPromptResponse } from '@/Interface';
|
|||
|
||||
import ModalDrawer from '@/components/ModalDrawer.vue';
|
||||
|
||||
import { workflowHelpers } from '@/mixins/workflowHelpers';
|
||||
import { useSettingsStore } from '@/stores/settings.store';
|
||||
import { useRootStore } from '@/stores/n8nRoot.store';
|
||||
import { createEventBus } from 'n8n-design-system/utils';
|
||||
|
@ -79,7 +78,6 @@ export default defineComponent({
|
|||
components: {
|
||||
ModalDrawer,
|
||||
},
|
||||
mixins: [workflowHelpers],
|
||||
props: ['isActive'],
|
||||
setup() {
|
||||
return {
|
||||
|
|
|
@ -45,11 +45,11 @@ import { NodeConnectionType, WorkflowDataProxy } from 'n8n-workflow';
|
|||
import VariableSelectorItem from '@/components/VariableSelectorItem.vue';
|
||||
import type { INodeUi, IVariableItemSelected, IVariableSelectorOption } from '@/Interface';
|
||||
|
||||
import { workflowHelpers } from '@/mixins/workflowHelpers';
|
||||
|
||||
import { useWorkflowsStore } from '@/stores/workflows.store';
|
||||
import { useRootStore } from '@/stores/n8nRoot.store';
|
||||
import { useNDVStore } from '@/stores/ndv.store';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { useWorkflowHelpers } from '@/composables/useWorkflowHelpers';
|
||||
|
||||
// Node types that should not be displayed in variable selector
|
||||
const SKIPPED_NODE_TYPES = [STICKY_NODE_TYPE];
|
||||
|
@ -59,8 +59,15 @@ export default defineComponent({
|
|||
components: {
|
||||
VariableSelectorItem,
|
||||
},
|
||||
mixins: [workflowHelpers],
|
||||
props: ['path', 'redactValues'],
|
||||
setup() {
|
||||
const router = useRouter();
|
||||
const workflowHelpers = useWorkflowHelpers(router);
|
||||
|
||||
return {
|
||||
workflowHelpers,
|
||||
};
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
variableFilter: '',
|
||||
|
@ -74,7 +81,10 @@ export default defineComponent({
|
|||
if (!activeNode) {
|
||||
return null;
|
||||
}
|
||||
return this.getParentMainInputNode(this.getCurrentWorkflow(), activeNode);
|
||||
return this.workflowHelpers.getParentMainInputNode(
|
||||
this.workflowHelpers.getCurrentWorkflow(),
|
||||
activeNode,
|
||||
);
|
||||
},
|
||||
extendAll(): boolean {
|
||||
if (this.variableFilter) {
|
||||
|
@ -87,7 +97,7 @@ export default defineComponent({
|
|||
return this.getFilterResults(this.variableFilter.toLowerCase(), 0);
|
||||
},
|
||||
workflow(): Workflow {
|
||||
return this.getCurrentWorkflow();
|
||||
return this.workflowHelpers.getCurrentWorkflow();
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
|
@ -482,7 +492,7 @@ export default defineComponent({
|
|||
parentNode[0],
|
||||
inputName,
|
||||
);
|
||||
const connectionInputData = this.connectionInputData(
|
||||
const connectionInputData = this.workflowHelpers.connectionInputData(
|
||||
parentNode,
|
||||
nodeName,
|
||||
inputName,
|
||||
|
|
|
@ -64,7 +64,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<MessageTyping ref="messageContainer" v-if="isLoading" />
|
||||
<MessageTyping v-if="isLoading" ref="messageContainer" />
|
||||
</div>
|
||||
<div v-if="node" class="logs-wrapper" data-test-id="lm-chat-logs">
|
||||
<n8n-text class="logs-title" tag="p" size="large">{{
|
||||
|
@ -149,6 +149,9 @@ import { useExternalHooks } from '@/composables/useExternalHooks';
|
|||
|
||||
// eslint-disable-next-line import/no-unresolved
|
||||
import MessageTyping from '@n8n/chat/components/MessageTyping.vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { useWorkflowHelpers } from '@/composables/useWorkflowHelpers';
|
||||
import { useNodeTypesStore } from '@/stores/nodeTypes.store';
|
||||
|
||||
const RunDataAi = defineAsyncComponent(
|
||||
async () => await import('@/components/RunDataAi/RunDataAi.vue'),
|
||||
|
@ -181,9 +184,12 @@ export default defineComponent({
|
|||
mixins: [workflowRun],
|
||||
setup(props, ctx) {
|
||||
const externalHooks = useExternalHooks();
|
||||
const router = useRouter();
|
||||
const workflowHelpers = useWorkflowHelpers(router);
|
||||
|
||||
return {
|
||||
externalHooks,
|
||||
workflowHelpers,
|
||||
...useToast(),
|
||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
||||
...workflowRun.setup?.(props, ctx),
|
||||
|
@ -201,7 +207,7 @@ export default defineComponent({
|
|||
},
|
||||
|
||||
computed: {
|
||||
...mapStores(useWorkflowsStore, useUIStore),
|
||||
...mapStores(useWorkflowsStore, useUIStore, useNodeTypesStore),
|
||||
isLoading(): boolean {
|
||||
return this.uiStore.isActionActive('workflowRunning');
|
||||
},
|
||||
|
@ -213,7 +219,7 @@ export default defineComponent({
|
|||
},
|
||||
methods: {
|
||||
displayExecution(executionId: string) {
|
||||
const workflow = this.getCurrentWorkflow();
|
||||
const workflow = this.workflowHelpers.getCurrentWorkflow();
|
||||
const route = this.$router.resolve({
|
||||
name: VIEWS.EXECUTION_PREVIEW,
|
||||
params: { name: workflow.id, executionId },
|
||||
|
@ -264,9 +270,9 @@ export default defineComponent({
|
|||
);
|
||||
return;
|
||||
}
|
||||
const workflow = this.getCurrentWorkflow();
|
||||
const workflow = this.workflowHelpers.getCurrentWorkflow();
|
||||
|
||||
const chatNode = this.workflowsStore.getNodes().find((node: INodeUi): boolean => {
|
||||
const chatNode = this.workflowHelpers.getNodes().find((node: INodeUi): boolean => {
|
||||
const nodeType = this.nodeTypesStore.getNodeType(node.type, node.typeVersion);
|
||||
if (!nodeType) return false;
|
||||
|
||||
|
@ -317,7 +323,7 @@ export default defineComponent({
|
|||
getChatMessages(): ChatMessage[] {
|
||||
if (!this.connectedNode) return [];
|
||||
|
||||
const workflow = this.getCurrentWorkflow();
|
||||
const workflow = this.workflowHelpers.getCurrentWorkflow();
|
||||
const connectedMemoryInputs =
|
||||
workflow.connectionsByDestinationNode[this.connectedNode.name][NodeConnectionType.AiMemory];
|
||||
if (!connectedMemoryInputs) return [];
|
||||
|
@ -369,7 +375,7 @@ export default defineComponent({
|
|||
return;
|
||||
}
|
||||
|
||||
const workflow = this.getCurrentWorkflow();
|
||||
const workflow = this.workflowHelpers.getCurrentWorkflow();
|
||||
const childNodes = workflow.getChildNodes(triggerNode.name);
|
||||
|
||||
for (const childNode of childNodes) {
|
||||
|
@ -389,7 +395,7 @@ export default defineComponent({
|
|||
},
|
||||
|
||||
getTriggerNode(): INode | null {
|
||||
const workflow = this.getCurrentWorkflow();
|
||||
const workflow = this.workflowHelpers.getCurrentWorkflow();
|
||||
const triggerNode = workflow.queryNodes((nodeType: INodeType) =>
|
||||
[CHAT_TRIGGER_NODE_TYPE, MANUAL_CHAT_TRIGGER_NODE_TYPE].includes(nodeType.description.name),
|
||||
);
|
||||
|
|
|
@ -6,7 +6,7 @@ import {
|
|||
} from './utils/ResourceMapper.utils';
|
||||
import { useNodeTypesStore } from '@/stores/nodeTypes.store';
|
||||
import { waitAllPromises } from '@/__tests__/utils';
|
||||
import * as workflowHelpers from '@/mixins/workflowHelpers';
|
||||
import * as workflowHelpers from '@/composables/useWorkflowHelpers';
|
||||
import ResourceMapper from '@/components/ResourceMapper/ResourceMapper.vue';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { createComponentRenderer } from '@/__tests__/render';
|
||||
|
|
|
@ -44,7 +44,7 @@ export function useDebounce() {
|
|||
): ReturnType<T> => {
|
||||
const debouncedFn = debounce(fn, options);
|
||||
|
||||
return debouncedFn(...inputParameters) as ReturnType<T>;
|
||||
return debouncedFn(...inputParameters);
|
||||
};
|
||||
|
||||
return {
|
||||
|
|
1211
packages/editor-ui/src/composables/useWorkflowHelpers.ts
Normal file
1211
packages/editor-ui/src/composables/useWorkflowHelpers.ts
Normal file
File diff suppressed because it is too large
Load diff
|
@ -2,7 +2,7 @@ import { createPinia, setActivePinia } from 'pinia';
|
|||
import { useSettingsStore } from '@/stores/settings.store';
|
||||
import { useWorkflowsStore } from '@/stores/workflows.store';
|
||||
import { setupServer } from '@/__tests__/server';
|
||||
import { executeData } from '@/mixins/workflowHelpers';
|
||||
import { executeData } from '@/composables/useWorkflowHelpers';
|
||||
import type { IExecutionResponse } from '@/Interface';
|
||||
|
||||
describe('workflowHelpers', () => {
|
||||
|
|
|
@ -6,16 +6,15 @@ import type { IDataObject } from 'n8n-workflow';
|
|||
import { Expression, ExpressionExtensions } from 'n8n-workflow';
|
||||
import { ensureSyntaxTree } from '@codemirror/language';
|
||||
|
||||
import { workflowHelpers } from '@/mixins/workflowHelpers';
|
||||
import { useNDVStore } from '@/stores/ndv.store';
|
||||
import { EXPRESSION_EDITOR_PARSER_TIMEOUT } from '@/constants';
|
||||
|
||||
import type { EditorView } from '@codemirror/view';
|
||||
import type { TargetItem } from '@/Interface';
|
||||
import type { Html, Plaintext, RawSegment, Resolvable, Segment } from '@/types/expressions';
|
||||
import { useWorkflowHelpers } from '@/composables/useWorkflowHelpers';
|
||||
|
||||
export const expressionManager = defineComponent({
|
||||
mixins: [workflowHelpers],
|
||||
props: {
|
||||
targetItem: {
|
||||
type: Object as PropType<TargetItem | null>,
|
||||
|
@ -197,6 +196,7 @@ export const expressionManager = defineComponent({
|
|||
|
||||
try {
|
||||
const ndvStore = useNDVStore();
|
||||
const workflowHelpers = useWorkflowHelpers(this.$router);
|
||||
if (!ndvStore.activeNode) {
|
||||
// e.g. credential modal
|
||||
result.resolved = Expression.resolveWithoutWorkflow(resolvable, this.additionalData);
|
||||
|
@ -211,7 +211,7 @@ export const expressionManager = defineComponent({
|
|||
additionalKeys: this.additionalData,
|
||||
};
|
||||
}
|
||||
result.resolved = this.resolveExpression('=' + resolvable, undefined, opts);
|
||||
result.resolved = workflowHelpers.resolveExpression('=' + resolvable, undefined, opts);
|
||||
}
|
||||
} catch (error) {
|
||||
result.resolved = `[${error.message}]`;
|
||||
|
|
|
@ -8,7 +8,6 @@ import type {
|
|||
import { useNodeHelpers } from '@/composables/useNodeHelpers';
|
||||
import { useTitleChange } from '@/composables/useTitleChange';
|
||||
import { useToast } from '@/composables/useToast';
|
||||
import { workflowHelpers } from '@/mixins/workflowHelpers';
|
||||
|
||||
import type {
|
||||
ExpressionError,
|
||||
|
@ -39,14 +38,19 @@ import { useOrchestrationStore } from '@/stores/orchestration.store';
|
|||
import { usePushConnectionStore } from '@/stores/pushConnection.store';
|
||||
import { useCollaborationStore } from '@/stores/collaboration.store';
|
||||
import { useExternalHooks } from '@/composables/useExternalHooks';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { useWorkflowHelpers } from '@/composables/useWorkflowHelpers';
|
||||
|
||||
export const pushConnection = defineComponent({
|
||||
mixins: [workflowHelpers],
|
||||
setup() {
|
||||
const router = useRouter();
|
||||
const workflowHelpers = useWorkflowHelpers(router);
|
||||
const nodeHelpers = useNodeHelpers();
|
||||
return {
|
||||
...useTitleChange(),
|
||||
...useToast(),
|
||||
nodeHelpers: useNodeHelpers(),
|
||||
nodeHelpers,
|
||||
workflowHelpers,
|
||||
};
|
||||
},
|
||||
data() {
|
||||
|
@ -312,7 +316,7 @@ export const pushConnection = defineComponent({
|
|||
|
||||
codeNodeEditorEventBus.emit('error-line-number', lineNumber || 'final');
|
||||
|
||||
const workflow = this.getCurrentWorkflow();
|
||||
const workflow = this.workflowHelpers.getCurrentWorkflow();
|
||||
if (runDataExecuted.waitTill !== undefined) {
|
||||
const activeExecutionId = this.workflowsStore.activeExecutionId;
|
||||
const workflowSettings = this.workflowsStore.workflowSettings;
|
||||
|
@ -328,7 +332,8 @@ export const pushConnection = defineComponent({
|
|||
globalLinkActionsEventBus.emit('registerGlobalLinkAction', {
|
||||
key: 'open-settings',
|
||||
action: async () => {
|
||||
if (this.workflowsStore.isNewWorkflow) await this.saveAsNewWorkflow();
|
||||
if (this.workflowsStore.isNewWorkflow)
|
||||
await this.workflowHelpers.saveAsNewWorkflow();
|
||||
this.uiStore.openModal(WORKFLOW_SETTINGS_MODAL_KEY);
|
||||
},
|
||||
});
|
||||
|
@ -357,7 +362,7 @@ export const pushConnection = defineComponent({
|
|||
) {
|
||||
const error = runDataExecuted.data.resultData.error as ExpressionError;
|
||||
|
||||
void this.getWorkflowDataToSave().then((workflowData) => {
|
||||
void this.workflowHelpers.getWorkflowDataToSave().then((workflowData) => {
|
||||
const eventData: IDataObject = {
|
||||
caused_by_credential: false,
|
||||
error_message: error.description,
|
||||
|
@ -366,7 +371,7 @@ export const pushConnection = defineComponent({
|
|||
node_graph_string: JSON.stringify(
|
||||
TelemetryHelpers.generateNodesGraph(
|
||||
workflowData as IWorkflowBase,
|
||||
this.getNodeTypes(),
|
||||
this.workflowHelpers.getNodeTypes(),
|
||||
).nodeGraph,
|
||||
),
|
||||
workflow_id: this.workflowsStore.workflowId,
|
||||
|
|
|
@ -2,7 +2,6 @@ import { defineComponent } from 'vue';
|
|||
import { mapStores } from 'pinia';
|
||||
import { useStorage } from '@/composables/useStorage';
|
||||
|
||||
import { workflowHelpers } from '@/mixins/workflowHelpers';
|
||||
import { useToast } from '@/composables/useToast';
|
||||
|
||||
import {
|
||||
|
@ -14,11 +13,15 @@ import { useUIStore } from '@/stores/ui.store';
|
|||
import { useSettingsStore } from '@/stores/settings.store';
|
||||
import { useWorkflowsStore } from '@/stores/workflows.store';
|
||||
import { useExternalHooks } from '@/composables/useExternalHooks';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { useWorkflowHelpers } from '@/composables/useWorkflowHelpers';
|
||||
|
||||
export const workflowActivate = defineComponent({
|
||||
mixins: [workflowHelpers],
|
||||
setup() {
|
||||
const router = useRouter();
|
||||
const workflowHelpers = useWorkflowHelpers(router);
|
||||
return {
|
||||
workflowHelpers,
|
||||
...useToast(),
|
||||
};
|
||||
},
|
||||
|
@ -45,7 +48,7 @@ export const workflowActivate = defineComponent({
|
|||
|
||||
let currWorkflowId: string | undefined = workflowId;
|
||||
if (!currWorkflowId || currWorkflowId === PLACEHOLDER_EMPTY_WORKFLOW_ID) {
|
||||
const saved = await this.saveCurrentWorkflow();
|
||||
const saved = await this.workflowHelpers.saveCurrentWorkflow();
|
||||
if (!saved) {
|
||||
this.updatingWorkflowActivation = false;
|
||||
return;
|
||||
|
@ -92,7 +95,7 @@ export const workflowActivate = defineComponent({
|
|||
return;
|
||||
}
|
||||
|
||||
await this.updateWorkflow(
|
||||
await this.workflowHelpers.updateWorkflow(
|
||||
{ workflowId: currWorkflowId, active: newActiveState },
|
||||
!this.uiStore.stateIsDirty,
|
||||
);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -18,7 +18,6 @@ import {
|
|||
|
||||
import { useToast } from '@/composables/useToast';
|
||||
import { useNodeHelpers } from '@/composables/useNodeHelpers';
|
||||
import { workflowHelpers } from '@/mixins/workflowHelpers';
|
||||
|
||||
import { FORM_TRIGGER_NODE_TYPE, WAIT_NODE_TYPE } from '@/constants';
|
||||
import { useTitleChange } from '@/composables/useTitleChange';
|
||||
|
@ -27,16 +26,20 @@ import { useUIStore } from '@/stores/ui.store';
|
|||
import { useWorkflowsStore } from '@/stores/workflows.store';
|
||||
import { openPopUpWindow } from '@/utils/executionUtils';
|
||||
import { useExternalHooks } from '@/composables/useExternalHooks';
|
||||
import { useWorkflowHelpers } from '@/composables/useWorkflowHelpers';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
export const workflowRun = defineComponent({
|
||||
mixins: [workflowHelpers],
|
||||
setup() {
|
||||
const nodeHelpers = useNodeHelpers();
|
||||
const router = useRouter();
|
||||
const workflowHelpers = useWorkflowHelpers(router);
|
||||
|
||||
return {
|
||||
...useTitleChange(),
|
||||
...useToast(),
|
||||
nodeHelpers,
|
||||
workflowHelpers,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
@ -81,7 +84,7 @@ export const workflowRun = defineComponent({
|
|||
| { triggerNode: string; nodeData: ITaskData; source?: string }
|
||||
| { source?: string },
|
||||
): Promise<IExecutionPushResponse | undefined> {
|
||||
const workflow = this.getCurrentWorkflow();
|
||||
const workflow = this.workflowHelpers.getCurrentWorkflow();
|
||||
|
||||
if (this.uiStore.isActionActive('workflowRunning')) {
|
||||
return;
|
||||
|
@ -97,7 +100,10 @@ export const workflowRun = defineComponent({
|
|||
const issuesExist = this.workflowsStore.nodesIssuesExist;
|
||||
if (issuesExist) {
|
||||
// If issues exist get all of the issues of all nodes
|
||||
const workflowIssues = this.checkReadyForExecution(workflow, options.destinationNode);
|
||||
const workflowIssues = this.workflowHelpers.checkReadyForExecution(
|
||||
workflow,
|
||||
options.destinationNode,
|
||||
);
|
||||
if (workflowIssues !== null) {
|
||||
const errorMessages = [];
|
||||
let nodeIssues: string[];
|
||||
|
@ -143,7 +149,7 @@ export const workflowRun = defineComponent({
|
|||
nodeName: options.destinationNode,
|
||||
});
|
||||
|
||||
await this.getWorkflowDataToSave().then((workflowData) => {
|
||||
await this.workflowHelpers.getWorkflowDataToSave().then((workflowData) => {
|
||||
this.$telemetry.track('Workflow execution preflight failed', {
|
||||
workflow_id: workflow.id,
|
||||
workflow_name: workflow.name,
|
||||
|
@ -152,7 +158,7 @@ export const workflowRun = defineComponent({
|
|||
node_graph_string: JSON.stringify(
|
||||
TelemetryHelpers.generateNodesGraph(
|
||||
workflowData as IWorkflowBase,
|
||||
this.getNodeTypes(),
|
||||
this.workflowHelpers.getNodeTypes(),
|
||||
).nodeGraph,
|
||||
),
|
||||
error_node_types: JSON.stringify(trackErrorNodeTypes),
|
||||
|
@ -231,10 +237,10 @@ export const workflowRun = defineComponent({
|
|||
}
|
||||
|
||||
if (this.workflowsStore.isNewWorkflow) {
|
||||
await this.saveCurrentWorkflow();
|
||||
await this.workflowHelpers.saveCurrentWorkflow();
|
||||
}
|
||||
|
||||
const workflowData = await this.getWorkflowDataToSave();
|
||||
const workflowData = await this.workflowHelpers.getWorkflowDataToSave();
|
||||
|
||||
const startRunData: IStartRunData = {
|
||||
workflowData,
|
||||
|
|
|
@ -2,7 +2,7 @@ import { createTestingPinia } from '@pinia/testing';
|
|||
import { createPinia, setActivePinia } from 'pinia';
|
||||
import { DateTime } from 'luxon';
|
||||
|
||||
import * as workflowHelpers from '@/mixins/workflowHelpers';
|
||||
import * as workflowHelpers from '@/composables/useWorkflowHelpers';
|
||||
import { dollarOptions } from '@/plugins/codemirror/completions/dollar.completions';
|
||||
import * as utils from '@/plugins/codemirror/completions/utils';
|
||||
import {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { resolveParameter } from '@/mixins/workflowHelpers';
|
||||
import { resolveParameter } from '@/composables/useWorkflowHelpers';
|
||||
import { prefixMatch, longestCommonPrefix } from './utils';
|
||||
import type { IDataObject } from 'n8n-workflow';
|
||||
import type { Completion, CompletionContext, CompletionResult } from '@codemirror/autocomplete';
|
||||
|
|
|
@ -2,7 +2,7 @@ import type { IDataObject, DocMetadata, NativeDoc } from 'n8n-workflow';
|
|||
import { Expression, ExpressionExtensions, NativeMethods } from 'n8n-workflow';
|
||||
import { DateTime } from 'luxon';
|
||||
import { i18n } from '@/plugins/i18n';
|
||||
import { resolveParameter } from '@/mixins/workflowHelpers';
|
||||
import { resolveParameter } from '@/composables/useWorkflowHelpers';
|
||||
import {
|
||||
setRank,
|
||||
hasNoParams,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import type { resolveParameter } from '@/mixins/workflowHelpers';
|
||||
import type { resolveParameter } from '@/composables/useWorkflowHelpers';
|
||||
import type { DocMetadata } from 'n8n-workflow';
|
||||
|
||||
export type Resolved = ReturnType<typeof resolveParameter>;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { NODE_TYPES_EXCLUDED_FROM_AUTOCOMPLETION } from '@/components/CodeNodeEditor/constants';
|
||||
import { CREDENTIAL_EDIT_MODAL_KEY, SPLIT_IN_BATCHES_NODE_TYPE } from '@/constants';
|
||||
import { useWorkflowsStore } from '@/stores/workflows.store';
|
||||
import { resolveParameter } from '@/mixins/workflowHelpers';
|
||||
import { resolveParameter } from '@/composables/useWorkflowHelpers';
|
||||
import { useNDVStore } from '@/stores/ndv.store';
|
||||
import { useUIStore } from '@/stores/ui.store';
|
||||
import type { Completion, CompletionContext } from '@codemirror/autocomplete';
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div :class="$style['content']" ref="nodeViewRootRef">
|
||||
<div ref="nodeViewRootRef" :class="$style['content']">
|
||||
<div
|
||||
id="node-view-root"
|
||||
class="node-view-root do-not-select"
|
||||
|
@ -258,7 +258,6 @@ import { useUniqueNodeName } from '@/composables/useUniqueNodeName';
|
|||
import { useI18n } from '@/composables/useI18n';
|
||||
import { useMessage } from '@/composables/useMessage';
|
||||
import { useToast } from '@/composables/useToast';
|
||||
import { workflowHelpers } from '@/mixins/workflowHelpers';
|
||||
import { workflowRun } from '@/mixins/workflowRun';
|
||||
|
||||
import NodeDetailsView from '@/components/NodeDetailsView.vue';
|
||||
|
@ -316,7 +315,7 @@ import type {
|
|||
ToggleNodeCreatorOptions,
|
||||
} from '@/Interface';
|
||||
|
||||
import type { Route, RawLocation } from 'vue-router';
|
||||
import { type Route, type RawLocation, useRouter } from 'vue-router';
|
||||
import { dataPinningEventBus, nodeViewEventBus } from '@/event-bus';
|
||||
import { useCanvasStore } from '@/stores/canvas.store';
|
||||
import { useCollaborationStore } from '@/stores/collaboration.store';
|
||||
|
@ -381,6 +380,7 @@ import { useDeviceSupport } from 'n8n-design-system';
|
|||
import { useDebounce } from '@/composables/useDebounce';
|
||||
import { useCanvasPanning } from '@/composables/useCanvasPanning';
|
||||
import { tryToParseNumber } from '@/utils/typesUtils';
|
||||
import { useWorkflowHelpers } from '@/composables/useWorkflowHelpers';
|
||||
|
||||
interface AddNodeOptions {
|
||||
position?: XYPosition;
|
||||
|
@ -412,7 +412,7 @@ export default defineComponent({
|
|||
ContextMenu,
|
||||
SetupWorkflowCredentialsButton,
|
||||
},
|
||||
mixins: [workflowHelpers, workflowRun],
|
||||
mixins: [workflowRun],
|
||||
async beforeRouteLeave(to, from, next) {
|
||||
if (
|
||||
getNodeViewTab(to) === MAIN_HEADER_TABS.EXECUTIONS ||
|
||||
|
@ -440,7 +440,7 @@ export default defineComponent({
|
|||
if (confirmModal === MODAL_CONFIRM) {
|
||||
// Make sure workflow id is empty when leaving the editor
|
||||
this.workflowsStore.setWorkflowId(PLACEHOLDER_EMPTY_WORKFLOW_ID);
|
||||
const saved = await this.saveCurrentWorkflow({}, false);
|
||||
const saved = await this.workflowHelpers.saveCurrentWorkflow({}, false);
|
||||
if (saved) {
|
||||
await this.settingsStore.fetchPromptsData();
|
||||
}
|
||||
|
@ -477,6 +477,7 @@ export default defineComponent({
|
|||
const nodeViewRootRef = ref(null);
|
||||
const nodeViewRef = ref(null);
|
||||
const onMouseMoveEnd = ref(null);
|
||||
const router = useRouter();
|
||||
|
||||
const ndvStore = useNDVStore();
|
||||
const externalHooks = useExternalHooks();
|
||||
|
@ -490,6 +491,7 @@ export default defineComponent({
|
|||
const deviceSupport = useDeviceSupport();
|
||||
const { callDebounced } = useDebounce();
|
||||
const canvasPanning = useCanvasPanning(nodeViewRootRef, { onMouseMoveEnd });
|
||||
const workflowHelpers = useWorkflowHelpers(router);
|
||||
|
||||
return {
|
||||
locale,
|
||||
|
@ -504,6 +506,7 @@ export default defineComponent({
|
|||
nodeViewRootRef,
|
||||
nodeViewRef,
|
||||
onMouseMoveEnd,
|
||||
workflowHelpers,
|
||||
callDebounced,
|
||||
...useCanvasMouseSelect(),
|
||||
...useGlobalLinkActions(),
|
||||
|
@ -1068,12 +1071,14 @@ export default defineComponent({
|
|||
this.uiStore.openModal(WORKFLOW_LM_CHAT_MODAL_KEY);
|
||||
},
|
||||
async onRunWorkflow() {
|
||||
void this.getWorkflowDataToSave().then((workflowData) => {
|
||||
void this.workflowHelpers.getWorkflowDataToSave().then((workflowData) => {
|
||||
const telemetryPayload = {
|
||||
workflow_id: this.workflowsStore.workflowId,
|
||||
node_graph_string: JSON.stringify(
|
||||
TelemetryHelpers.generateNodesGraph(workflowData as IWorkflowBase, this.getNodeTypes())
|
||||
.nodeGraph,
|
||||
TelemetryHelpers.generateNodesGraph(
|
||||
workflowData as IWorkflowBase,
|
||||
this.workflowHelpers.getNodeTypes(),
|
||||
).nodeGraph,
|
||||
),
|
||||
};
|
||||
this.$telemetry.track('User clicked execute workflow button', telemetryPayload);
|
||||
|
@ -1150,7 +1155,7 @@ export default defineComponent({
|
|||
this.nodeHelpers.updateNodesExecutionIssues();
|
||||
},
|
||||
async onSaveKeyboardShortcut(e: KeyboardEvent) {
|
||||
let saved = await this.saveCurrentWorkflow();
|
||||
let saved = await this.workflowHelpers.saveCurrentWorkflow();
|
||||
if (saved) {
|
||||
await this.settingsStore.fetchPromptsData();
|
||||
|
||||
|
@ -1636,7 +1641,7 @@ export default defineComponent({
|
|||
return;
|
||||
}
|
||||
|
||||
const workflow = this.getCurrentWorkflow();
|
||||
const workflow = this.workflowHelpers.getCurrentWorkflow();
|
||||
|
||||
if (!workflow.connectionsByDestinationNode.hasOwnProperty(lastSelectedNode.name)) {
|
||||
return;
|
||||
|
@ -1664,7 +1669,7 @@ export default defineComponent({
|
|||
return;
|
||||
}
|
||||
|
||||
const workflow = this.getCurrentWorkflow();
|
||||
const workflow = this.workflowHelpers.getCurrentWorkflow();
|
||||
|
||||
if (!workflow.connectionsByDestinationNode.hasOwnProperty(lastSelectedNode.name)) {
|
||||
return;
|
||||
|
@ -1793,9 +1798,13 @@ export default defineComponent({
|
|||
this.deselectAllNodes();
|
||||
|
||||
// Get all upstream nodes and select them
|
||||
const workflow = this.getCurrentWorkflow();
|
||||
const workflow = this.workflowHelpers.getCurrentWorkflow();
|
||||
|
||||
const checkNodes = this.getConnectedNodes('upstream', workflow, lastSelectedNode.name);
|
||||
const checkNodes = this.workflowHelpers.getConnectedNodes(
|
||||
'upstream',
|
||||
workflow,
|
||||
lastSelectedNode.name,
|
||||
);
|
||||
for (const nodeName of checkNodes) {
|
||||
this.nodeSelectedByName(nodeName);
|
||||
}
|
||||
|
@ -1812,9 +1821,13 @@ export default defineComponent({
|
|||
this.deselectAllNodes();
|
||||
|
||||
// Get all downstream nodes and select them
|
||||
const workflow = this.getCurrentWorkflow();
|
||||
const workflow = this.workflowHelpers.getCurrentWorkflow();
|
||||
|
||||
const checkNodes = this.getConnectedNodes('downstream', workflow, lastSelectedNode.name);
|
||||
const checkNodes = this.workflowHelpers.getConnectedNodes(
|
||||
'downstream',
|
||||
workflow,
|
||||
lastSelectedNode.name,
|
||||
);
|
||||
for (const nodeName of checkNodes) {
|
||||
this.nodeSelectedByName(nodeName);
|
||||
}
|
||||
|
@ -1826,9 +1839,13 @@ export default defineComponent({
|
|||
pushDownstreamNodes(sourceNodeName: string, margin: number, recordHistory = false) {
|
||||
const sourceNode = this.workflowsStore.nodesByName[sourceNodeName];
|
||||
|
||||
const workflow = this.getCurrentWorkflow();
|
||||
const workflow = this.workflowHelpers.getCurrentWorkflow();
|
||||
|
||||
const checkNodes = this.getConnectedNodes('downstream', workflow, sourceNodeName);
|
||||
const checkNodes = this.workflowHelpers.getConnectedNodes(
|
||||
'downstream',
|
||||
workflow,
|
||||
sourceNodeName,
|
||||
);
|
||||
for (const nodeName of checkNodes) {
|
||||
const node = this.workflowsStore.nodesByName[nodeName];
|
||||
const oldPosition = node.position;
|
||||
|
@ -1877,7 +1894,7 @@ export default defineComponent({
|
|||
...data,
|
||||
};
|
||||
|
||||
this.removeForeignCredentialsFromWorkflow(
|
||||
this.workflowHelpers.removeForeignCredentialsFromWorkflow(
|
||||
workflowToCopy,
|
||||
this.credentialsStore.allCredentials,
|
||||
);
|
||||
|
@ -1962,12 +1979,14 @@ export default defineComponent({
|
|||
}
|
||||
this.stopExecutionInProgress = false;
|
||||
|
||||
void this.getWorkflowDataToSave().then((workflowData) => {
|
||||
void this.workflowHelpers.getWorkflowDataToSave().then((workflowData) => {
|
||||
const trackProps = {
|
||||
workflow_id: this.workflowsStore.workflowId,
|
||||
node_graph_string: JSON.stringify(
|
||||
TelemetryHelpers.generateNodesGraph(workflowData as IWorkflowBase, this.getNodeTypes())
|
||||
.nodeGraph,
|
||||
TelemetryHelpers.generateNodesGraph(
|
||||
workflowData as IWorkflowBase,
|
||||
this.workflowHelpers.getNodeTypes(),
|
||||
).nodeGraph,
|
||||
),
|
||||
};
|
||||
|
||||
|
@ -2090,9 +2109,9 @@ export default defineComponent({
|
|||
workflowData.nodes.forEach((node: INode) => {
|
||||
//generate new webhookId if workflow already contains a node with the same webhookId
|
||||
if (node.webhookId && UPDATE_WEBHOOK_ID_NODE_TYPES.includes(node.type)) {
|
||||
const isDuplicate = Object.values(this.getCurrentWorkflow().nodes).some(
|
||||
(n) => n.webhookId === node.webhookId,
|
||||
);
|
||||
const isDuplicate = Object.values(
|
||||
this.workflowHelpers.getCurrentWorkflow().nodes,
|
||||
).some((n) => n.webhookId === node.webhookId);
|
||||
if (isDuplicate) {
|
||||
node.webhookId = uuid();
|
||||
}
|
||||
|
@ -2114,13 +2133,17 @@ export default defineComponent({
|
|||
const currInstanceId = this.rootStore.instanceId;
|
||||
|
||||
const nodeGraph = JSON.stringify(
|
||||
TelemetryHelpers.generateNodesGraph(workflowData as IWorkflowBase, this.getNodeTypes(), {
|
||||
nodeIdMap,
|
||||
sourceInstanceId:
|
||||
workflowData.meta && workflowData.meta.instanceId !== currInstanceId
|
||||
? workflowData.meta.instanceId
|
||||
: '',
|
||||
}).nodeGraph,
|
||||
TelemetryHelpers.generateNodesGraph(
|
||||
workflowData as IWorkflowBase,
|
||||
this.workflowHelpers.getNodeTypes(),
|
||||
{
|
||||
nodeIdMap,
|
||||
sourceInstanceId:
|
||||
workflowData.meta && workflowData.meta.instanceId !== currInstanceId
|
||||
? workflowData.meta.instanceId
|
||||
: '',
|
||||
},
|
||||
).nodeGraph,
|
||||
);
|
||||
if (source === 'paste') {
|
||||
this.$telemetry.track('User pasted nodes', {
|
||||
|
@ -2147,7 +2170,7 @@ export default defineComponent({
|
|||
// Fix the node position as it could be totally offscreen
|
||||
// and the pasted nodes would so not be directly visible to
|
||||
// the user
|
||||
this.updateNodePositions(
|
||||
this.workflowHelpers.updateNodePositions(
|
||||
workflowData,
|
||||
NodeViewUtils.getNewNodePosition(this.nodes, this.lastClickPosition),
|
||||
);
|
||||
|
@ -2387,7 +2410,7 @@ export default defineComponent({
|
|||
|
||||
if (
|
||||
nodeTypeData.maxNodes !== undefined &&
|
||||
this.getNodeTypeCount(nodeTypeName) >= nodeTypeData.maxNodes
|
||||
this.workflowHelpers.getNodeTypeCount(nodeTypeName) >= nodeTypeData.maxNodes
|
||||
) {
|
||||
this.showMaxNodeTypeError(nodeTypeData);
|
||||
return;
|
||||
|
@ -2428,7 +2451,7 @@ export default defineComponent({
|
|||
this.canvasStore.newNodeInsertPosition = null;
|
||||
} else {
|
||||
let yOffset = 0;
|
||||
const workflow = this.getCurrentWorkflow();
|
||||
const workflow = this.workflowHelpers.getCurrentWorkflow();
|
||||
|
||||
if (lastSelectedConnection) {
|
||||
const sourceNodeType = this.nodeTypesStore.getNodeType(
|
||||
|
@ -2487,8 +2510,8 @@ export default defineComponent({
|
|||
const lastSelectedNodeWorkflow = workflow.getNode(lastSelectedNode.name);
|
||||
const lastSelectedInputs = NodeHelpers.getNodeInputs(
|
||||
workflow,
|
||||
lastSelectedNodeWorkflow!,
|
||||
lastSelectedNodeType!,
|
||||
lastSelectedNodeWorkflow,
|
||||
lastSelectedNodeType,
|
||||
);
|
||||
const lastSelectedInputTypes = NodeHelpers.getConnectionTypes(lastSelectedInputs);
|
||||
|
||||
|
@ -2512,7 +2535,7 @@ export default defineComponent({
|
|||
const inputs = NodeHelpers.getNodeInputs(
|
||||
workflow,
|
||||
lastSelectedNode,
|
||||
lastSelectedNodeType!,
|
||||
lastSelectedNodeType,
|
||||
);
|
||||
const inputsTypes = NodeHelpers.getConnectionTypes(inputs);
|
||||
|
||||
|
@ -2698,7 +2721,7 @@ export default defineComponent({
|
|||
if (
|
||||
lastSelectedEndpoint &&
|
||||
this.checkNodeConnectionAllowed(
|
||||
lastSelectedNode!,
|
||||
lastSelectedNode,
|
||||
newNodeData,
|
||||
lastSelectedEndpoint.scope as NodeConnectionType,
|
||||
)
|
||||
|
@ -2752,7 +2775,7 @@ export default defineComponent({
|
|||
},
|
||||
getNodeCreatorFilter(nodeName: string, outputType?: NodeConnectionType) {
|
||||
let filter;
|
||||
const workflow = this.getCurrentWorkflow();
|
||||
const workflow = this.workflowHelpers.getCurrentWorkflow();
|
||||
const workflowNode = workflow.getNode(nodeName);
|
||||
if (!workflowNode) return { nodes: [] };
|
||||
|
||||
|
@ -2884,11 +2907,11 @@ export default defineComponent({
|
|||
);
|
||||
|
||||
if (targetNodeType?.inputs?.length) {
|
||||
const workflow = this.getCurrentWorkflow();
|
||||
const workflow = this.workflowHelpers.getCurrentWorkflow();
|
||||
const workflowNode = workflow.getNode(targetNode.name);
|
||||
let inputs: Array<ConnectionTypes | INodeInputConfiguration> = [];
|
||||
if (targetNodeType) {
|
||||
inputs = NodeHelpers.getNodeInputs(workflow, workflowNode!, targetNodeType);
|
||||
inputs = NodeHelpers.getNodeInputs(workflow, workflowNode, targetNodeType);
|
||||
}
|
||||
|
||||
for (const input of inputs || []) {
|
||||
|
@ -3543,7 +3566,7 @@ export default defineComponent({
|
|||
},
|
||||
);
|
||||
if (confirmModal === MODAL_CONFIRM) {
|
||||
const saved = await this.saveCurrentWorkflow();
|
||||
const saved = await this.workflowHelpers.saveCurrentWorkflow();
|
||||
if (saved) await this.settingsStore.fetchPromptsData();
|
||||
} else if (confirmModal === MODAL_CLOSE) {
|
||||
return;
|
||||
|
@ -3869,13 +3892,13 @@ export default defineComponent({
|
|||
// connect nodes before/after deleted node
|
||||
const nodeType = this.nodeTypesStore.getNodeType(node.type, node.typeVersion);
|
||||
|
||||
const workflow = this.getCurrentWorkflow();
|
||||
const workflow = this.workflowHelpers.getCurrentWorkflow();
|
||||
const workflowNode = workflow.getNode(node.name);
|
||||
let inputs: Array<ConnectionTypes | INodeInputConfiguration> = [];
|
||||
let outputs: Array<ConnectionTypes | INodeOutputConfiguration> = [];
|
||||
if (nodeType) {
|
||||
inputs = NodeHelpers.getNodeInputs(workflow, workflowNode!, nodeType);
|
||||
outputs = NodeHelpers.getNodeOutputs(workflow, workflowNode!, nodeType);
|
||||
inputs = NodeHelpers.getNodeInputs(workflow, workflowNode, nodeType);
|
||||
outputs = NodeHelpers.getNodeOutputs(workflow, workflowNode, nodeType);
|
||||
}
|
||||
|
||||
if (outputs.length === 1 && inputs.length === 1) {
|
||||
|
@ -4000,7 +4023,7 @@ export default defineComponent({
|
|||
this.historyStore.startRecordingUndo();
|
||||
}
|
||||
|
||||
const activeNodeName = this.activeNode && this.activeNode.name;
|
||||
const activeNodeName = this.activeNode?.name;
|
||||
const isActive = activeNodeName === currentName;
|
||||
if (isActive) {
|
||||
this.renamingActive = true;
|
||||
|
@ -4009,7 +4032,7 @@ export default defineComponent({
|
|||
newName = this.uniqueNodeName(newName);
|
||||
|
||||
// Rename the node and update the connections
|
||||
const workflow = this.getCurrentWorkflow(true);
|
||||
const workflow = this.workflowHelpers.getCurrentWorkflow(true);
|
||||
workflow.renameNode(currentName, newName);
|
||||
|
||||
if (trackHistory) {
|
||||
|
@ -4249,7 +4272,7 @@ export default defineComponent({
|
|||
|
||||
// Get how many of the nodes of the types which have
|
||||
// a max limit set already exist
|
||||
const nodeTypesCount = this.getNodeTypesMaxCount();
|
||||
const nodeTypesCount = this.workflowHelpers.getNodeTypesMaxCount();
|
||||
|
||||
let oldName: string;
|
||||
let newName: string;
|
||||
|
@ -4334,7 +4357,7 @@ export default defineComponent({
|
|||
|
||||
// Create a workflow with the new nodes and connections that we can use
|
||||
// the rename method
|
||||
const tempWorkflow: Workflow = this.getWorkflow(createNodes, newConnections);
|
||||
const tempWorkflow: Workflow = this.workflowHelpers.getWorkflow(createNodes, newConnections);
|
||||
|
||||
// Rename all the nodes of which the name changed
|
||||
for (oldName in nodeNameTable) {
|
||||
|
@ -4398,7 +4421,7 @@ export default defineComponent({
|
|||
const exportNodeNames: string[] = [];
|
||||
|
||||
for (const node of nodes) {
|
||||
nodeData = this.getNodeDataToSave(node);
|
||||
nodeData = this.workflowHelpers.getNodeDataToSave(node);
|
||||
exportNodeNames.push(node.name);
|
||||
|
||||
data.nodes.push(nodeData);
|
||||
|
@ -4728,7 +4751,7 @@ export default defineComponent({
|
|||
}
|
||||
|
||||
const lastAddedNode = this.nodes[this.nodes.length - 1];
|
||||
const workflow = this.getCurrentWorkflow();
|
||||
const workflow = this.workflowHelpers.getCurrentWorkflow();
|
||||
const lastNodeInputs = workflow.getParentNodesByDepth(lastAddedNode.name, 1);
|
||||
|
||||
// If the last added node has multiple inputs, move them down
|
||||
|
@ -4748,7 +4771,7 @@ export default defineComponent({
|
|||
},
|
||||
|
||||
async saveCurrentWorkflowExternal(callback: () => void) {
|
||||
await this.saveCurrentWorkflow();
|
||||
await this.workflowHelpers.saveCurrentWorkflow();
|
||||
callback?.();
|
||||
},
|
||||
setSuspendRecordingDetachedConnections(suspend: boolean) {
|
||||
|
|
|
@ -57,7 +57,6 @@ import TemplateDetails from '@/components/TemplateDetails.vue';
|
|||
import TemplateList from '@/components/TemplateList.vue';
|
||||
import TemplatesView from './TemplatesView.vue';
|
||||
|
||||
import { workflowHelpers } from '@/mixins/workflowHelpers';
|
||||
import type {
|
||||
ITemplatesCollection,
|
||||
ITemplatesCollectionFull,
|
||||
|
@ -80,7 +79,6 @@ export default defineComponent({
|
|||
TemplateList,
|
||||
TemplatesView,
|
||||
},
|
||||
mixins: [workflowHelpers],
|
||||
setup() {
|
||||
const externalHooks = useExternalHooks();
|
||||
|
||||
|
|
|
@ -64,7 +64,6 @@ import TemplatesView from './TemplatesView.vue';
|
|||
import WorkflowPreview from '@/components/WorkflowPreview.vue';
|
||||
|
||||
import type { ITemplatesWorkflowFull } from '@/Interface';
|
||||
import { workflowHelpers } from '@/mixins/workflowHelpers';
|
||||
import { setPageTitle } from '@/utils/htmlUtils';
|
||||
import { useTemplatesStore } from '@/stores/templates.store';
|
||||
import { usePostHog } from '@/stores/posthog.store';
|
||||
|
@ -79,7 +78,6 @@ export default defineComponent({
|
|||
TemplatesView,
|
||||
WorkflowPreview,
|
||||
},
|
||||
mixins: [workflowHelpers],
|
||||
setup() {
|
||||
const externalHooks = useExternalHooks();
|
||||
|
||||
|
|
Loading…
Reference in a new issue