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