mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-16 09:36:44 +00:00
refactor(editor): Move templates api to @n8n/rest-api-client package (no-changelog) (#16542)
This commit is contained in:
@@ -18,3 +18,6 @@ CHANGELOG.md
|
||||
**/*.js
|
||||
**/*.json
|
||||
**/*.jsonc
|
||||
|
||||
# Auto-generated
|
||||
**/components.d.ts
|
||||
|
||||
@@ -14,7 +14,10 @@ export * from './roles';
|
||||
export * from './settings';
|
||||
export * from './module-settings';
|
||||
export * from './sso';
|
||||
export * from './tags';
|
||||
export * from './templates';
|
||||
export * from './ui';
|
||||
export * from './versions';
|
||||
export * from './webhooks';
|
||||
export * from './workflowHistory';
|
||||
export * from './workflows';
|
||||
|
||||
7
packages/frontend/@n8n/rest-api-client/src/api/tags.ts
Normal file
7
packages/frontend/@n8n/rest-api-client/src/api/tags.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export interface ITag {
|
||||
id: string;
|
||||
name: string;
|
||||
usageCount?: number;
|
||||
createdAt?: string;
|
||||
updatedAt?: string;
|
||||
}
|
||||
195
packages/frontend/@n8n/rest-api-client/src/api/templates.ts
Normal file
195
packages/frontend/@n8n/rest-api-client/src/api/templates.ts
Normal file
@@ -0,0 +1,195 @@
|
||||
import type { RawAxiosRequestHeaders } from 'axios';
|
||||
import type { INode, INodeCredentialsDetails } from 'n8n-workflow';
|
||||
|
||||
import type { VersionNode } from './versions';
|
||||
import type { WorkflowData } from './workflows';
|
||||
import { get } from '../utils';
|
||||
|
||||
export interface IWorkflowTemplateNode
|
||||
extends Pick<
|
||||
INode,
|
||||
'name' | 'type' | 'position' | 'parameters' | 'typeVersion' | 'webhookId' | 'id' | 'disabled'
|
||||
> {
|
||||
// The credentials in a template workflow have a different type than in a regular workflow
|
||||
credentials?: IWorkflowTemplateNodeCredentials;
|
||||
}
|
||||
|
||||
export interface IWorkflowTemplateNodeCredentials {
|
||||
[key: string]: string | INodeCredentialsDetails;
|
||||
}
|
||||
|
||||
export interface IWorkflowTemplate {
|
||||
id: number;
|
||||
name: string;
|
||||
workflow: Pick<WorkflowData, 'connections' | 'settings' | 'pinData'> & {
|
||||
nodes: IWorkflowTemplateNode[];
|
||||
};
|
||||
}
|
||||
|
||||
export interface ITemplatesNode extends VersionNode {
|
||||
id: number;
|
||||
categories?: ITemplatesCategory[];
|
||||
}
|
||||
|
||||
export interface ITemplatesCollection {
|
||||
id: number;
|
||||
name: string;
|
||||
nodes: ITemplatesNode[];
|
||||
workflows: Array<{ id: number }>;
|
||||
}
|
||||
|
||||
interface ITemplatesImage {
|
||||
id: number;
|
||||
url: string;
|
||||
}
|
||||
|
||||
interface ITemplatesCollectionExtended extends ITemplatesCollection {
|
||||
description: string | null;
|
||||
image: ITemplatesImage[];
|
||||
categories: ITemplatesCategory[];
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
export interface ITemplatesCollectionFull extends ITemplatesCollectionExtended {
|
||||
full: true;
|
||||
}
|
||||
|
||||
export interface ITemplatesCollectionResponse extends ITemplatesCollectionExtended {
|
||||
workflows: ITemplatesWorkflow[];
|
||||
}
|
||||
|
||||
/**
|
||||
* A template without the actual workflow definition
|
||||
*/
|
||||
|
||||
export interface ITemplatesWorkflow {
|
||||
id: number;
|
||||
createdAt: string;
|
||||
name: string;
|
||||
nodes: ITemplatesNode[];
|
||||
totalViews: number;
|
||||
user: {
|
||||
username: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface ITemplatesWorkflowInfo {
|
||||
nodeCount: number;
|
||||
nodeTypes: {
|
||||
[key: string]: {
|
||||
count: number;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export type TemplateSearchFacet = {
|
||||
field_name: string;
|
||||
sampled: boolean;
|
||||
stats: {
|
||||
total_values: number;
|
||||
};
|
||||
counts: Array<{
|
||||
count: number;
|
||||
highlighted: string;
|
||||
value: string;
|
||||
}>;
|
||||
};
|
||||
|
||||
export interface ITemplatesWorkflowResponse extends ITemplatesWorkflow, IWorkflowTemplate {
|
||||
description: string | null;
|
||||
image: ITemplatesImage[];
|
||||
categories: ITemplatesCategory[];
|
||||
workflowInfo: ITemplatesWorkflowInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* A template with also the full workflow definition
|
||||
*/
|
||||
|
||||
export interface ITemplatesWorkflowFull extends ITemplatesWorkflowResponse {
|
||||
full: true;
|
||||
}
|
||||
|
||||
export interface ITemplatesQuery {
|
||||
categories: string[];
|
||||
search: string;
|
||||
}
|
||||
|
||||
export interface ITemplatesCategory {
|
||||
id: number;
|
||||
name: string;
|
||||
}
|
||||
|
||||
function stringifyArray(arr: string[]) {
|
||||
return arr.join(',');
|
||||
}
|
||||
|
||||
export async function testHealthEndpoint(apiEndpoint: string) {
|
||||
return await get(apiEndpoint, '/health');
|
||||
}
|
||||
|
||||
export async function getCategories(
|
||||
apiEndpoint: string,
|
||||
headers?: RawAxiosRequestHeaders,
|
||||
): Promise<{ categories: ITemplatesCategory[] }> {
|
||||
return await get(apiEndpoint, '/templates/categories', undefined, headers);
|
||||
}
|
||||
|
||||
export async function getCollections(
|
||||
apiEndpoint: string,
|
||||
query: ITemplatesQuery,
|
||||
headers?: RawAxiosRequestHeaders,
|
||||
): Promise<{ collections: ITemplatesCollection[] }> {
|
||||
return await get(
|
||||
apiEndpoint,
|
||||
'/templates/collections',
|
||||
{ category: query.categories, search: query.search },
|
||||
headers,
|
||||
);
|
||||
}
|
||||
|
||||
export async function getWorkflows(
|
||||
apiEndpoint: string,
|
||||
query: { page: number; limit: number; categories: string[]; search: string },
|
||||
headers?: RawAxiosRequestHeaders,
|
||||
): Promise<{
|
||||
totalWorkflows: number;
|
||||
workflows: ITemplatesWorkflow[];
|
||||
filters: TemplateSearchFacet[];
|
||||
}> {
|
||||
return await get(
|
||||
apiEndpoint,
|
||||
'/templates/search',
|
||||
{
|
||||
page: query.page,
|
||||
rows: query.limit,
|
||||
category: stringifyArray(query.categories),
|
||||
search: query.search,
|
||||
},
|
||||
headers,
|
||||
);
|
||||
}
|
||||
|
||||
export async function getCollectionById(
|
||||
apiEndpoint: string,
|
||||
collectionId: string,
|
||||
headers?: RawAxiosRequestHeaders,
|
||||
): Promise<{ collection: ITemplatesCollectionResponse }> {
|
||||
return await get(apiEndpoint, `/templates/collections/${collectionId}`, undefined, headers);
|
||||
}
|
||||
|
||||
export async function getTemplateById(
|
||||
apiEndpoint: string,
|
||||
templateId: string,
|
||||
headers?: RawAxiosRequestHeaders,
|
||||
): Promise<{ workflow: ITemplatesWorkflowResponse }> {
|
||||
return await get(apiEndpoint, `/templates/workflows/${templateId}`, undefined, headers);
|
||||
}
|
||||
|
||||
export async function getWorkflowTemplate(
|
||||
apiEndpoint: string,
|
||||
templateId: string,
|
||||
headers?: RawAxiosRequestHeaders,
|
||||
): Promise<IWorkflowTemplate> {
|
||||
return await get(apiEndpoint, `/workflows/templates/${templateId}`, undefined, headers);
|
||||
}
|
||||
42
packages/frontend/@n8n/rest-api-client/src/api/workflows.ts
Normal file
42
packages/frontend/@n8n/rest-api-client/src/api/workflows.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import type { IWorkflowSettings, IConnections, INode, IPinData } from 'n8n-workflow';
|
||||
|
||||
import type { ITag } from './tags';
|
||||
|
||||
export interface WorkflowMetadata {
|
||||
onboardingId?: string;
|
||||
templateId?: string;
|
||||
instanceId?: string;
|
||||
templateCredsSetupCompleted?: boolean;
|
||||
}
|
||||
|
||||
// Simple version of n8n-workflow.Workflow
|
||||
export interface WorkflowData {
|
||||
id?: string;
|
||||
name?: string;
|
||||
active?: boolean;
|
||||
nodes: INode[];
|
||||
connections: IConnections;
|
||||
settings?: IWorkflowSettings;
|
||||
tags?: string[];
|
||||
pinData?: IPinData;
|
||||
versionId?: string;
|
||||
meta?: WorkflowMetadata;
|
||||
}
|
||||
|
||||
export interface WorkflowDataUpdate {
|
||||
id?: string;
|
||||
name?: string;
|
||||
nodes?: INode[];
|
||||
connections?: IConnections;
|
||||
settings?: IWorkflowSettings;
|
||||
active?: boolean;
|
||||
tags?: ITag[] | string[]; // string[] when store or requested, ITag[] from API response
|
||||
pinData?: IPinData;
|
||||
versionId?: string;
|
||||
meta?: WorkflowMetadata;
|
||||
parentFolderId?: string;
|
||||
}
|
||||
|
||||
export interface WorkflowDataCreate extends WorkflowDataUpdate {
|
||||
projectId?: string;
|
||||
}
|
||||
@@ -41,15 +41,21 @@ import type {
|
||||
INodeExecutionData,
|
||||
INodeProperties,
|
||||
NodeConnectionType,
|
||||
INodeCredentialsDetails,
|
||||
StartNodeData,
|
||||
IPersonalizationSurveyAnswersV4,
|
||||
AnnotationVote,
|
||||
ITaskData,
|
||||
ISourceData,
|
||||
} from 'n8n-workflow';
|
||||
import type { Version, VersionNode } from '@n8n/rest-api-client/api/versions';
|
||||
import type { Version } from '@n8n/rest-api-client/api/versions';
|
||||
import type { Cloud, InstanceUsage } from '@n8n/rest-api-client/api/cloudPlans';
|
||||
import type {
|
||||
WorkflowMetadata,
|
||||
WorkflowData,
|
||||
WorkflowDataCreate,
|
||||
WorkflowDataUpdate,
|
||||
} from '@n8n/rest-api-client/api/workflows';
|
||||
import type { ITag } from '@n8n/rest-api-client/api/tags';
|
||||
|
||||
import type {
|
||||
AI_NODE_CREATOR_VIEW,
|
||||
@@ -203,7 +209,7 @@ export interface IAiData {
|
||||
}
|
||||
|
||||
export interface IStartRunData {
|
||||
workflowData: IWorkflowData;
|
||||
workflowData: WorkflowData;
|
||||
startNodes?: StartNodeData[];
|
||||
destinationNode?: string;
|
||||
runData?: IRunData;
|
||||
@@ -230,49 +236,17 @@ export interface ITableData {
|
||||
};
|
||||
}
|
||||
|
||||
// Simple version of n8n-workflow.Workflow
|
||||
export interface IWorkflowData {
|
||||
id?: string;
|
||||
name?: string;
|
||||
active?: boolean;
|
||||
nodes: INode[];
|
||||
connections: IConnections;
|
||||
settings?: IWorkflowSettings;
|
||||
tags?: string[];
|
||||
pinData?: IPinData;
|
||||
versionId?: string;
|
||||
meta?: WorkflowMetadata;
|
||||
}
|
||||
|
||||
export interface IWorkflowDataUpdate {
|
||||
id?: string;
|
||||
name?: string;
|
||||
nodes?: INode[];
|
||||
connections?: IConnections;
|
||||
settings?: IWorkflowSettings;
|
||||
active?: boolean;
|
||||
tags?: ITag[] | string[]; // string[] when store or requested, ITag[] from API response
|
||||
pinData?: IPinData;
|
||||
versionId?: string;
|
||||
meta?: WorkflowMetadata;
|
||||
parentFolderId?: string;
|
||||
}
|
||||
|
||||
export interface IWorkflowDataCreate extends IWorkflowDataUpdate {
|
||||
projectId?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Workflow data with mandatory `templateId`
|
||||
* This is used to identify sample workflows that we create for onboarding
|
||||
*/
|
||||
export interface WorkflowDataWithTemplateId extends Omit<IWorkflowDataCreate, 'meta'> {
|
||||
export interface WorkflowDataWithTemplateId extends Omit<WorkflowDataCreate, 'meta'> {
|
||||
meta: WorkflowMetadata & {
|
||||
templateId: Required<WorkflowMetadata>['templateId'];
|
||||
};
|
||||
}
|
||||
|
||||
export interface IWorkflowToShare extends IWorkflowDataUpdate {
|
||||
export interface IWorkflowToShare extends WorkflowDataUpdate {
|
||||
meta: WorkflowMetadata;
|
||||
}
|
||||
|
||||
@@ -281,38 +255,10 @@ export interface NewWorkflowResponse {
|
||||
defaultSettings: IWorkflowSettings;
|
||||
}
|
||||
|
||||
export interface IWorkflowTemplateNode
|
||||
extends Pick<
|
||||
INodeUi,
|
||||
'name' | 'type' | 'position' | 'parameters' | 'typeVersion' | 'webhookId' | 'id' | 'disabled'
|
||||
> {
|
||||
// The credentials in a template workflow have a different type than in a regular workflow
|
||||
credentials?: IWorkflowTemplateNodeCredentials;
|
||||
}
|
||||
|
||||
export interface IWorkflowTemplateNodeCredentials {
|
||||
[key: string]: string | INodeCredentialsDetails;
|
||||
}
|
||||
|
||||
export interface IWorkflowTemplate {
|
||||
id: number;
|
||||
name: string;
|
||||
workflow: Pick<IWorkflowData, 'connections' | 'settings' | 'pinData'> & {
|
||||
nodes: IWorkflowTemplateNode[];
|
||||
};
|
||||
}
|
||||
|
||||
export interface INewWorkflowData {
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface WorkflowMetadata {
|
||||
onboardingId?: string;
|
||||
templateId?: string;
|
||||
instanceId?: string;
|
||||
templateCredsSetupCompleted?: boolean;
|
||||
}
|
||||
|
||||
// Almost identical to cli.Interfaces.ts
|
||||
export interface IWorkflowDb {
|
||||
id: string;
|
||||
@@ -627,93 +573,6 @@ export interface IUserPermissions {
|
||||
};
|
||||
}
|
||||
|
||||
export interface ITemplatesCollection {
|
||||
id: number;
|
||||
name: string;
|
||||
nodes: ITemplatesNode[];
|
||||
workflows: Array<{ id: number }>;
|
||||
}
|
||||
|
||||
interface ITemplatesImage {
|
||||
id: number;
|
||||
url: string;
|
||||
}
|
||||
|
||||
interface ITemplatesCollectionExtended extends ITemplatesCollection {
|
||||
description: string | null;
|
||||
image: ITemplatesImage[];
|
||||
categories: ITemplatesCategory[];
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
export interface ITemplatesCollectionFull extends ITemplatesCollectionExtended {
|
||||
full: true;
|
||||
}
|
||||
|
||||
export interface ITemplatesCollectionResponse extends ITemplatesCollectionExtended {
|
||||
workflows: ITemplatesWorkflow[];
|
||||
}
|
||||
|
||||
/**
|
||||
* A template without the actual workflow definition
|
||||
*/
|
||||
export interface ITemplatesWorkflow {
|
||||
id: number;
|
||||
createdAt: string;
|
||||
name: string;
|
||||
nodes: ITemplatesNode[];
|
||||
totalViews: number;
|
||||
user: {
|
||||
username: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface ITemplatesWorkflowInfo {
|
||||
nodeCount: number;
|
||||
nodeTypes: {
|
||||
[key: string]: {
|
||||
count: number;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export type TemplateSearchFacet = {
|
||||
field_name: string;
|
||||
sampled: boolean;
|
||||
stats: {
|
||||
total_values: number;
|
||||
};
|
||||
counts: Array<{
|
||||
count: number;
|
||||
highlighted: string;
|
||||
value: string;
|
||||
}>;
|
||||
};
|
||||
|
||||
export interface ITemplatesWorkflowResponse extends ITemplatesWorkflow, IWorkflowTemplate {
|
||||
description: string | null;
|
||||
image: ITemplatesImage[];
|
||||
categories: ITemplatesCategory[];
|
||||
workflowInfo: ITemplatesWorkflowInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* A template with also the full workflow definition
|
||||
*/
|
||||
export interface ITemplatesWorkflowFull extends ITemplatesWorkflowResponse {
|
||||
full: true;
|
||||
}
|
||||
|
||||
export interface ITemplatesQuery {
|
||||
categories: string[];
|
||||
search: string;
|
||||
}
|
||||
|
||||
export interface ITemplatesCategory {
|
||||
id: number;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export type WorkflowCallerPolicyDefaultOption = 'any' | 'none' | 'workflowsFromAList';
|
||||
|
||||
export interface IWorkflowSettings extends IWorkflowSettingsWorkflow {
|
||||
@@ -893,13 +752,6 @@ export type NodeTypeSelectedPayload = {
|
||||
export interface SubcategorizedNodeTypes {
|
||||
[subcategory: string]: INodeCreateElement[];
|
||||
}
|
||||
export interface ITag {
|
||||
id: string;
|
||||
name: string;
|
||||
usageCount?: number;
|
||||
createdAt?: string;
|
||||
updatedAt?: string;
|
||||
}
|
||||
|
||||
export interface ITagRow {
|
||||
tag?: ITag;
|
||||
@@ -911,11 +763,6 @@ export interface ITagRow {
|
||||
canDelete?: boolean;
|
||||
}
|
||||
|
||||
export interface ITemplatesNode extends VersionNode {
|
||||
id: number;
|
||||
categories?: ITemplatesCategory[];
|
||||
}
|
||||
|
||||
export interface INodeMetadata {
|
||||
parametersLastUpdatedAt?: number;
|
||||
pinnedDataLastUpdatedAt?: number;
|
||||
@@ -1130,28 +977,6 @@ export interface INodeTypesState {
|
||||
nodeTypes: NodeTypesByTypeNameAndVersion;
|
||||
}
|
||||
|
||||
export interface ITemplateState {
|
||||
categories: ITemplatesCategory[];
|
||||
collections: { [id: string]: ITemplatesCollection };
|
||||
workflows: { [id: string]: ITemplatesWorkflow | ITemplatesWorkflowFull };
|
||||
workflowSearches: {
|
||||
[search: string]: {
|
||||
workflowIds: string[];
|
||||
totalWorkflows: number;
|
||||
loadingMore?: boolean;
|
||||
categories?: ITemplatesCategory[];
|
||||
};
|
||||
};
|
||||
collectionSearches: {
|
||||
[search: string]: {
|
||||
collectionIds: string[];
|
||||
};
|
||||
};
|
||||
currentSessionId: string;
|
||||
previousSessionId: string;
|
||||
currentN8nPath: string;
|
||||
}
|
||||
|
||||
export interface IVersionsState {
|
||||
versionNotificationSettings: IVersionNotificationSettings;
|
||||
nextVersions: Version[];
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Factory } from 'miragejs';
|
||||
import type { ITag } from '@/Interface';
|
||||
import type { ITag } from '@n8n/rest-api-client/api/tags';
|
||||
import { faker } from '@faker-js/faker';
|
||||
|
||||
export const tagFactory = Factory.extend<ITag>({
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ITag } from '@/Interface';
|
||||
import type { ITag } from '@n8n/rest-api-client/api/tags';
|
||||
export const tags: ITag[] = [
|
||||
{
|
||||
id: '1',
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ITag } from '@/Interface';
|
||||
import type { ITag } from '@n8n/rest-api-client/api/tags';
|
||||
import { Model } from 'miragejs';
|
||||
import type { ModelDefinition } from 'miragejs/-types';
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ITag } from '@/Interface';
|
||||
import type { ITag } from '@n8n/rest-api-client/api/tags';
|
||||
import type { IRestApiContext } from '@n8n/rest-api-client';
|
||||
import { makeRestApiRequest } from '@n8n/rest-api-client';
|
||||
import type { CreateOrUpdateTagRequestDto, RetrieveTagQueryDto } from '@n8n/api-types';
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
import type { RawAxiosRequestHeaders } from 'axios';
|
||||
import type {
|
||||
ITemplatesCategory,
|
||||
ITemplatesCollection,
|
||||
ITemplatesQuery,
|
||||
ITemplatesWorkflow,
|
||||
ITemplatesCollectionResponse,
|
||||
ITemplatesWorkflowResponse,
|
||||
IWorkflowTemplate,
|
||||
TemplateSearchFacet,
|
||||
} from '@/Interface';
|
||||
import { get } from '@n8n/rest-api-client';
|
||||
|
||||
function stringifyArray(arr: string[]) {
|
||||
return arr.join(',');
|
||||
}
|
||||
|
||||
export async function testHealthEndpoint(apiEndpoint: string) {
|
||||
return await get(apiEndpoint, '/health');
|
||||
}
|
||||
|
||||
export async function getCategories(
|
||||
apiEndpoint: string,
|
||||
headers?: RawAxiosRequestHeaders,
|
||||
): Promise<{ categories: ITemplatesCategory[] }> {
|
||||
return await get(apiEndpoint, '/templates/categories', undefined, headers);
|
||||
}
|
||||
|
||||
export async function getCollections(
|
||||
apiEndpoint: string,
|
||||
query: ITemplatesQuery,
|
||||
headers?: RawAxiosRequestHeaders,
|
||||
): Promise<{ collections: ITemplatesCollection[] }> {
|
||||
return await get(
|
||||
apiEndpoint,
|
||||
'/templates/collections',
|
||||
{ category: query.categories, search: query.search },
|
||||
headers,
|
||||
);
|
||||
}
|
||||
|
||||
export async function getWorkflows(
|
||||
apiEndpoint: string,
|
||||
query: { page: number; limit: number; categories: string[]; search: string },
|
||||
headers?: RawAxiosRequestHeaders,
|
||||
): Promise<{
|
||||
totalWorkflows: number;
|
||||
workflows: ITemplatesWorkflow[];
|
||||
filters: TemplateSearchFacet[];
|
||||
}> {
|
||||
return await get(
|
||||
apiEndpoint,
|
||||
'/templates/search',
|
||||
{
|
||||
page: query.page,
|
||||
rows: query.limit,
|
||||
category: stringifyArray(query.categories),
|
||||
search: query.search,
|
||||
},
|
||||
headers,
|
||||
);
|
||||
}
|
||||
|
||||
export async function getCollectionById(
|
||||
apiEndpoint: string,
|
||||
collectionId: string,
|
||||
headers?: RawAxiosRequestHeaders,
|
||||
): Promise<{ collection: ITemplatesCollectionResponse }> {
|
||||
return await get(apiEndpoint, `/templates/collections/${collectionId}`, undefined, headers);
|
||||
}
|
||||
|
||||
export async function getTemplateById(
|
||||
apiEndpoint: string,
|
||||
templateId: string,
|
||||
headers?: RawAxiosRequestHeaders,
|
||||
): Promise<{ workflow: ITemplatesWorkflowResponse }> {
|
||||
return await get(apiEndpoint, `/templates/workflows/${templateId}`, undefined, headers);
|
||||
}
|
||||
|
||||
export async function getWorkflowTemplate(
|
||||
apiEndpoint: string,
|
||||
templateId: string,
|
||||
headers?: RawAxiosRequestHeaders,
|
||||
): Promise<IWorkflowTemplate> {
|
||||
return await get(apiEndpoint, `/workflows/templates/${templateId}`, undefined, headers);
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import { useUsersStore } from '@/stores/users.store';
|
||||
import { computed, watch, ref, onBeforeUnmount } from 'vue';
|
||||
import AskAssistantChat from '@n8n/design-system/components/AskAssistantChat/AskAssistantChat.vue';
|
||||
import { useTelemetry } from '@/composables/useTelemetry';
|
||||
import type { IWorkflowDataUpdate } from '@/Interface';
|
||||
import type { WorkflowDataUpdate } from '@n8n/rest-api-client/api/workflows';
|
||||
import { nodeViewEventBus } from '@/event-bus';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import { useI18n } from '@n8n/i18n';
|
||||
@@ -37,7 +37,7 @@ async function onUserMessage(content: string) {
|
||||
await builderStore.initBuilderChat(content, 'chat');
|
||||
}
|
||||
|
||||
function fixWorkflowStickiesPosition(workflowData: IWorkflowDataUpdate): IWorkflowDataUpdate {
|
||||
function fixWorkflowStickiesPosition(workflowData: WorkflowDataUpdate): WorkflowDataUpdate {
|
||||
const STICKY_WIDTH = 480;
|
||||
const HEADERS_HEIGHT = 40;
|
||||
const NEW_LINE_HEIGHT = 20;
|
||||
@@ -76,7 +76,7 @@ function fixWorkflowStickiesPosition(workflowData: IWorkflowDataUpdate): IWorkfl
|
||||
}
|
||||
|
||||
function onInsertWorkflow(code: string) {
|
||||
let workflowData: IWorkflowDataUpdate;
|
||||
let workflowData: WorkflowDataUpdate;
|
||||
try {
|
||||
workflowData = JSON.parse(code);
|
||||
} catch (error) {
|
||||
|
||||
@@ -6,7 +6,7 @@ import WorkflowTagsDropdown from '@/components/WorkflowTagsDropdown.vue';
|
||||
import Modal from '@/components/Modal.vue';
|
||||
import { useSettingsStore } from '@/stores/settings.store';
|
||||
import { useWorkflowsStore } from '@/stores/workflows.store';
|
||||
import type { IWorkflowDataUpdate } from '@/Interface';
|
||||
import type { WorkflowDataUpdate } from '@n8n/rest-api-client/api/workflows';
|
||||
import { createEventBus, type EventBus } from '@n8n/utils/event-bus';
|
||||
import { useCredentialsStore } from '@/stores/credentials.store';
|
||||
import { useWorkflowHelpers } from '@/composables/useWorkflowHelpers';
|
||||
@@ -86,7 +86,7 @@ const save = async (): Promise<void> => {
|
||||
isSaving.value = true;
|
||||
|
||||
try {
|
||||
let workflowToUpdate: IWorkflowDataUpdate | undefined;
|
||||
let workflowToUpdate: WorkflowDataUpdate | undefined;
|
||||
if (currentWorkflowId !== PLACEHOLDER_EMPTY_WORKFLOW_ID) {
|
||||
const {
|
||||
createdAt,
|
||||
|
||||
@@ -47,10 +47,10 @@ import { computed, ref, useCssModule, useTemplateRef, watch } from 'vue';
|
||||
import type {
|
||||
ActionDropdownItem,
|
||||
FolderShortInfo,
|
||||
IWorkflowDataUpdate,
|
||||
IWorkflowDb,
|
||||
IWorkflowToShare,
|
||||
} from '@/Interface';
|
||||
import type { WorkflowDataUpdate } from '@n8n/rest-api-client/api/workflows';
|
||||
import { usePageRedirectionHelper } from '@/composables/usePageRedirectionHelper';
|
||||
import { useTelemetry } from '@/composables/useTelemetry';
|
||||
import type { PathItem } from '@n8n/design-system/components/N8nBreadcrumbs/Breadcrumbs.vue';
|
||||
@@ -407,7 +407,7 @@ async function handleFileImport(): Promise<void> {
|
||||
if (inputRef?.files && inputRef.files.length !== 0) {
|
||||
const reader = new FileReader();
|
||||
reader.onload = () => {
|
||||
let workflowData: IWorkflowDataUpdate;
|
||||
let workflowData: WorkflowDataUpdate;
|
||||
try {
|
||||
workflowData = JSON.parse(reader.result as string);
|
||||
} catch (error) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import NodeIcon from '@/components/NodeIcon.vue';
|
||||
import type { ITemplatesNode } from '@/Interface';
|
||||
import type { ITemplatesNode } from '@n8n/rest-api-client/api/templates';
|
||||
import { filterTemplateNodes } from '@/utils/nodeTypesUtils';
|
||||
|
||||
const props = withDefaults(
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed, onMounted, onBeforeUnmount, nextTick } from 'vue';
|
||||
import type { ComponentInstance } from 'vue';
|
||||
import type { ITag } from '@/Interface';
|
||||
import type { ITag } from '@n8n/rest-api-client/api/tags';
|
||||
import IntersectionObserver from './IntersectionObserver.vue';
|
||||
import IntersectionObserved from './IntersectionObserved.vue';
|
||||
import { createEventBus } from '@n8n/utils/event-bus';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue';
|
||||
import { onClickOutside } from '@vueuse/core';
|
||||
import type { ITag } from '@/Interface';
|
||||
import type { ITag } from '@n8n/rest-api-client/api/tags';
|
||||
import { MAX_TAG_NAME_LENGTH } from '@/constants';
|
||||
import { N8nOption, N8nSelect } from '@n8n/design-system';
|
||||
import type { EventBus } from '@n8n/utils/event-bus';
|
||||
|
||||
@@ -4,7 +4,7 @@ import { useI18n } from '@n8n/i18n';
|
||||
import { useToast } from '@/composables/useToast';
|
||||
import { useAnnotationTagsStore } from '@/stores/tags.store';
|
||||
import TagsManager from './TagsManager.vue';
|
||||
import type { ITag } from '@/Interface';
|
||||
import type { ITag } from '@n8n/rest-api-client/api/tags';
|
||||
import { ANNOTATION_TAGS_MANAGER_MODAL_KEY } from '@/constants';
|
||||
|
||||
const i18n = useI18n();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, onMounted } from 'vue';
|
||||
import type { ITag } from '@/Interface';
|
||||
import type { ITag } from '@n8n/rest-api-client/api/tags';
|
||||
import TagsView from '@/components/TagsManager/TagsView/TagsView.vue';
|
||||
import NoTagsView from '@/components/TagsManager/NoTagsView.vue';
|
||||
import Modal from '@/components/Modal.vue';
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue';
|
||||
import type { ITag, ITagRow } from '@/Interface';
|
||||
import type { ITag } from '@n8n/rest-api-client/api/tags';
|
||||
import type { ITagRow } from '@/Interface';
|
||||
import { useI18n } from '@n8n/i18n';
|
||||
import TagsTableHeader from '@/components/TagsManager/TagsView/TagsTableHeader.vue';
|
||||
import TagsTable from '@/components/TagsManager/TagsView/TagsTable.vue';
|
||||
|
||||
@@ -4,7 +4,7 @@ import { useI18n } from '@n8n/i18n';
|
||||
import { useToast } from '@/composables/useToast';
|
||||
import { useTagsStore } from '@/stores/tags.store';
|
||||
import TagsManager from './TagsManager.vue';
|
||||
import type { ITag } from '@/Interface';
|
||||
import type { ITag } from '@n8n/rest-api-client/api/tags';
|
||||
import { TAGS_MANAGER_MODAL_KEY } from '@/constants';
|
||||
|
||||
const i18n = useI18n();
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import { abbreviateNumber } from '@/utils/typesUtils';
|
||||
import NodeList from './NodeList.vue';
|
||||
import TimeAgo from '@/components/TimeAgo.vue';
|
||||
import type { ITemplatesWorkflow } from '@/Interface';
|
||||
import type { ITemplatesWorkflow } from '@n8n/rest-api-client/api/templates';
|
||||
import { useI18n } from '@n8n/i18n';
|
||||
import type { BaseTextKey } from '@n8n/i18n';
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import type {
|
||||
ITemplatesCollectionFull,
|
||||
ITemplatesNode,
|
||||
ITemplatesWorkflow,
|
||||
} from '@/Interface';
|
||||
} from '@n8n/rest-api-client/api/templates';
|
||||
import { useTemplatesStore } from '@/stores/templates.store';
|
||||
import TimeAgo from '@/components/TimeAgo.vue';
|
||||
import { isFullTemplatesCollection, isTemplatesWorkflow } from '@/utils/templates/typeGuards';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed, ref, watch } from 'vue';
|
||||
import type { ITemplatesCategory } from '@/Interface';
|
||||
import type { ITemplatesCategory } from '@n8n/rest-api-client/api/templates';
|
||||
import { useI18n } from '@n8n/i18n';
|
||||
|
||||
interface Props {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script lang="ts" setup>
|
||||
import { onBeforeUnmount, onMounted, ref } from 'vue';
|
||||
import TemplateCard from './TemplateCard.vue';
|
||||
import type { ITemplatesWorkflow } from '@/Interface';
|
||||
import type { ITemplatesWorkflow } from '@n8n/rest-api-client/api/templates';
|
||||
import { useI18n } from '@n8n/i18n';
|
||||
|
||||
interface Props {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import Card from '@/components/CollectionWorkflowCard.vue';
|
||||
import NodeList from '@/components/NodeList.vue';
|
||||
import { useI18n } from '@n8n/i18n';
|
||||
import type { ITemplatesCollection } from '@/Interface';
|
||||
import type { ITemplatesCollection } from '@n8n/rest-api-client/api/templates';
|
||||
|
||||
withDefaults(
|
||||
defineProps<{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { nextTick, onBeforeMount, onMounted, ref, watch } from 'vue';
|
||||
import type { ITemplatesCollection } from '@/Interface';
|
||||
import type { ITemplatesCollection } from '@n8n/rest-api-client/api/templates';
|
||||
import Card from '@/components/CollectionWorkflowCard.vue';
|
||||
import TemplatesInfoCard from '@/components/TemplatesInfoCard.vue';
|
||||
import { VueAgile } from 'vue-agile';
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
import { onMounted, onBeforeUnmount, ref, computed, watch } from 'vue';
|
||||
import { useI18n } from '@n8n/i18n';
|
||||
import { useToast } from '@/composables/useToast';
|
||||
import type { IWorkflowDb, IWorkflowTemplate } from '@/Interface';
|
||||
import type { IWorkflowDb } from '@/Interface';
|
||||
import type { IWorkflowTemplate } from '@n8n/rest-api-client/api/templates';
|
||||
import { useExecutionsStore } from '@/stores/executions.store';
|
||||
|
||||
const props = withDefaults(
|
||||
|
||||
@@ -22,7 +22,7 @@ import { useProjectsStore } from '@/stores/projects.store';
|
||||
import { useTelemetry } from '@/composables/useTelemetry';
|
||||
import { VIEWS } from '@/constants';
|
||||
import { SAMPLE_SUBWORKFLOW_TRIGGER_ID, SAMPLE_SUBWORKFLOW_WORKFLOW } from '@/constants.workflows';
|
||||
import type { IWorkflowDataCreate } from '@/Interface';
|
||||
import type { WorkflowDataCreate } from '@n8n/rest-api-client/api/workflows';
|
||||
import { useDocumentVisibility } from '@/composables/useDocumentVisibility';
|
||||
|
||||
export interface Props {
|
||||
@@ -36,7 +36,7 @@ export interface Props {
|
||||
forceShowExpression?: boolean;
|
||||
parameterIssues?: string[];
|
||||
parameter: INodeProperties;
|
||||
sampleWorkflow?: IWorkflowDataCreate;
|
||||
sampleWorkflow?: WorkflowDataCreate;
|
||||
newResourceLabel?: string;
|
||||
}
|
||||
|
||||
@@ -254,7 +254,7 @@ const onAddResourceClicked = async () => {
|
||||
(w) => w.name && new RegExp(workflowName).test(w.name),
|
||||
);
|
||||
|
||||
const workflow: IWorkflowDataCreate = {
|
||||
const workflow: WorkflowDataCreate = {
|
||||
...sampleWorkflow,
|
||||
name: `${workflowName} ${sampleSubWorkflows.length + 1}`,
|
||||
};
|
||||
|
||||
@@ -2,12 +2,8 @@
|
||||
import { ref, computed, onMounted } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { useToast } from '@/composables/useToast';
|
||||
import type {
|
||||
ITimeoutHMS,
|
||||
IWorkflowDataUpdate,
|
||||
IWorkflowSettings,
|
||||
IWorkflowShortResponse,
|
||||
} from '@/Interface';
|
||||
import type { ITimeoutHMS, IWorkflowSettings, IWorkflowShortResponse } from '@/Interface';
|
||||
import type { WorkflowDataUpdate } from '@n8n/rest-api-client/api/workflows';
|
||||
import Modal from '@/components/Modal.vue';
|
||||
import {
|
||||
EnterpriseEditionFeature,
|
||||
@@ -298,7 +294,7 @@ const convertToHMS = (num: number): ITimeoutHMS => {
|
||||
|
||||
const saveSettings = async () => {
|
||||
// Set that the active state should be changed
|
||||
const data: IWorkflowDataUpdate & { settings: IWorkflowSettings } = {
|
||||
const data: WorkflowDataUpdate & { settings: IWorkflowSettings } = {
|
||||
settings: workflowSettings.value,
|
||||
};
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import { computed } from 'vue';
|
||||
import TagsContainer from './TagsContainer.vue';
|
||||
import { useTagsStore } from '@/stores/tags.store';
|
||||
import type { ITag } from '@/Interface';
|
||||
import type { ITag } from '@n8n/rest-api-client/api/tags';
|
||||
|
||||
interface Props {
|
||||
tagIds: string[];
|
||||
|
||||
@@ -14,7 +14,8 @@ import { useRoute, useRouter } from 'vue-router';
|
||||
|
||||
import type { BaseTextKey } from '@n8n/i18n';
|
||||
import type { Scope } from '@n8n/permissions';
|
||||
import type { BaseFolderItem, BaseResource, ITag, ResourceParentFolder } from '@/Interface';
|
||||
import type { ITag } from '@n8n/rest-api-client/api/tags';
|
||||
import type { BaseFolderItem, BaseResource, ResourceParentFolder } from '@/Interface';
|
||||
import { isSharedResource, isResourceSortableByDate } from '@/utils/typeGuards';
|
||||
import { useN8nLocalStorage } from '@/composables/useN8nLocalStorage';
|
||||
|
||||
|
||||
@@ -11,14 +11,8 @@ import { NodeConnectionTypes, NodeHelpers, UserError } from 'n8n-workflow';
|
||||
import { useCanvasOperations } from '@/composables/useCanvasOperations';
|
||||
import type { CanvasConnection, CanvasNode } from '@/types';
|
||||
import { CanvasConnectionMode } from '@/types';
|
||||
import type {
|
||||
ICredentialsResponse,
|
||||
IExecutionResponse,
|
||||
INodeUi,
|
||||
IWorkflowDb,
|
||||
IWorkflowTemplate,
|
||||
IWorkflowTemplateNode,
|
||||
} from '@/Interface';
|
||||
import type { ICredentialsResponse, IExecutionResponse, INodeUi, IWorkflowDb } from '@/Interface';
|
||||
import type { IWorkflowTemplate, IWorkflowTemplateNode } from '@n8n/rest-api-client/api/templates';
|
||||
import { RemoveNodeCommand, ReplaceNodeParametersCommand } from '@/models/history';
|
||||
import { useWorkflowsStore } from '@/stores/workflows.store';
|
||||
import { useUIStore } from '@/stores/ui.store';
|
||||
|
||||
@@ -7,15 +7,14 @@ import type {
|
||||
AddedNodesAndConnections,
|
||||
IExecutionResponse,
|
||||
INodeUi,
|
||||
ITag,
|
||||
IUsedCredential,
|
||||
IWorkflowData,
|
||||
IWorkflowDataUpdate,
|
||||
IWorkflowDb,
|
||||
IWorkflowTemplate,
|
||||
WorkflowDataWithTemplateId,
|
||||
XYPosition,
|
||||
} from '@/Interface';
|
||||
import type { ITag } from '@n8n/rest-api-client/api/tags';
|
||||
import type { IWorkflowTemplate } from '@n8n/rest-api-client/api/templates';
|
||||
import type { WorkflowData, WorkflowDataUpdate } from '@n8n/rest-api-client/api/workflows';
|
||||
import { useDataSchema } from '@/composables/useDataSchema';
|
||||
import { useExternalHooks } from '@/composables/useExternalHooks';
|
||||
import { useI18n } from '@n8n/i18n';
|
||||
@@ -1627,7 +1626,7 @@ export function useCanvasOperations() {
|
||||
* Import operations
|
||||
*/
|
||||
|
||||
function removeUnknownCredentials(workflow: IWorkflowDataUpdate) {
|
||||
function removeUnknownCredentials(workflow: WorkflowDataUpdate) {
|
||||
if (!workflow?.nodes) return;
|
||||
|
||||
for (const node of workflow.nodes) {
|
||||
@@ -1644,9 +1643,9 @@ export function useCanvasOperations() {
|
||||
}
|
||||
|
||||
async function addImportedNodesToWorkflow(
|
||||
data: IWorkflowDataUpdate,
|
||||
data: WorkflowDataUpdate,
|
||||
{ trackBulk = true, trackHistory = false, viewport = DEFAULT_VIEWPORT_BOUNDARIES } = {},
|
||||
): Promise<IWorkflowDataUpdate> {
|
||||
): Promise<WorkflowDataUpdate> {
|
||||
// Because nodes with the same name maybe already exist, it could
|
||||
// be needed that they have to be renamed. Also could it be possible
|
||||
// that nodes are not allowed to be created because they have a create
|
||||
@@ -1818,7 +1817,7 @@ export function useCanvasOperations() {
|
||||
}
|
||||
|
||||
async function importWorkflowData(
|
||||
workflowData: IWorkflowDataUpdate,
|
||||
workflowData: WorkflowDataUpdate,
|
||||
source: string,
|
||||
{
|
||||
importTags = true,
|
||||
@@ -1831,7 +1830,7 @@ export function useCanvasOperations() {
|
||||
trackHistory?: boolean;
|
||||
viewport?: ViewportBoundaries;
|
||||
} = {},
|
||||
): Promise<IWorkflowDataUpdate> {
|
||||
): Promise<WorkflowDataUpdate> {
|
||||
uiStore.resetLastInteractedWith();
|
||||
|
||||
// If it is JSON check if it looks on the first look like data we can use
|
||||
@@ -1947,7 +1946,7 @@ export function useCanvasOperations() {
|
||||
}
|
||||
}
|
||||
|
||||
async function importWorkflowTags(workflowData: IWorkflowDataUpdate) {
|
||||
async function importWorkflowTags(workflowData: WorkflowDataUpdate) {
|
||||
const allTags = await tagsStore.fetchAll();
|
||||
const tagNames = new Set(allTags.map((tag) => tag.name));
|
||||
|
||||
@@ -1978,8 +1977,8 @@ export function useCanvasOperations() {
|
||||
workflowsStore.addWorkflowTagIds(tagIds);
|
||||
}
|
||||
|
||||
async function fetchWorkflowDataFromUrl(url: string): Promise<IWorkflowDataUpdate | undefined> {
|
||||
let workflowData: IWorkflowDataUpdate;
|
||||
async function fetchWorkflowDataFromUrl(url: string): Promise<WorkflowDataUpdate | undefined> {
|
||||
let workflowData: WorkflowDataUpdate;
|
||||
|
||||
canvasStore.startLoading();
|
||||
try {
|
||||
@@ -1994,12 +1993,12 @@ export function useCanvasOperations() {
|
||||
return workflowData;
|
||||
}
|
||||
|
||||
function getNodesToSave(nodes: INode[]): IWorkflowData {
|
||||
function getNodesToSave(nodes: INode[]): WorkflowData {
|
||||
const data = {
|
||||
nodes: [] as INodeUi[],
|
||||
connections: {} as IConnections,
|
||||
pinData: {} as IPinData,
|
||||
} satisfies IWorkflowData;
|
||||
} satisfies WorkflowData;
|
||||
|
||||
const exportedNodeNames = new Set<string>();
|
||||
|
||||
|
||||
@@ -14,7 +14,8 @@ import type {
|
||||
} from 'n8n-workflow';
|
||||
|
||||
import { useRunWorkflow } from '@/composables/useRunWorkflow';
|
||||
import type { IExecutionResponse, IStartRunData, IWorkflowData } from '@/Interface';
|
||||
import type { IExecutionResponse, IStartRunData } from '@/Interface';
|
||||
import type { WorkflowData } from '@n8n/rest-api-client/api/workflows';
|
||||
import { useWorkflowsStore } from '@/stores/workflows.store';
|
||||
import { useUIStore } from '@/stores/ui.store';
|
||||
import { useWorkflowHelpers } from '@/composables/useWorkflowHelpers';
|
||||
@@ -244,7 +245,7 @@ describe('useRunWorkflow({ router })', () => {
|
||||
disabled: false,
|
||||
},
|
||||
],
|
||||
} as unknown as IWorkflowData);
|
||||
} as unknown as WorkflowData);
|
||||
|
||||
const result = await runWorkflow({});
|
||||
|
||||
@@ -278,7 +279,7 @@ describe('useRunWorkflow({ router })', () => {
|
||||
pinData: {
|
||||
Slack: [{ json: { value: 'data2' } }],
|
||||
},
|
||||
} as unknown as IWorkflowData);
|
||||
} as unknown as WorkflowData);
|
||||
|
||||
const mockExecutionResponse = { executionId: '123' };
|
||||
|
||||
@@ -291,7 +292,7 @@ describe('useRunWorkflow({ router })', () => {
|
||||
vi.mocked(workflowHelpers).getWorkflowDataToSave.mockResolvedValue({
|
||||
id: 'workflowId',
|
||||
nodes: [],
|
||||
} as unknown as IWorkflowData);
|
||||
} as unknown as WorkflowData);
|
||||
vi.mocked(workflowsStore).getWorkflowRunData = {
|
||||
NodeName: [],
|
||||
};
|
||||
@@ -328,7 +329,7 @@ describe('useRunWorkflow({ router })', () => {
|
||||
vi.mocked(workflowHelpers).getWorkflowDataToSave.mockResolvedValue({
|
||||
id: 'workflowId',
|
||||
nodes: [],
|
||||
} as unknown as IWorkflowData);
|
||||
} as unknown as WorkflowData);
|
||||
vi.mocked(workflowsStore).getWorkflowRunData = {
|
||||
NodeName: [],
|
||||
};
|
||||
@@ -350,7 +351,7 @@ describe('useRunWorkflow({ router })', () => {
|
||||
vi.mocked(workflowHelpers).getWorkflowDataToSave.mockResolvedValue({
|
||||
id: 'workflowId',
|
||||
nodes: [],
|
||||
} as unknown as IWorkflowData);
|
||||
} as unknown as WorkflowData);
|
||||
vi.mocked(workflowsStore).getWorkflowRunData = {
|
||||
NodeName: [],
|
||||
};
|
||||
@@ -391,7 +392,7 @@ describe('useRunWorkflow({ router })', () => {
|
||||
vi.mocked(workflowHelpers).getWorkflowDataToSave.mockResolvedValue({
|
||||
id: 'workflowId',
|
||||
nodes: [],
|
||||
} as unknown as IWorkflowData);
|
||||
} as unknown as WorkflowData);
|
||||
|
||||
vi.mocked(workflowsStore).getWorkflowRunData = {
|
||||
[parentNodeName]: [
|
||||
@@ -465,7 +466,7 @@ describe('useRunWorkflow({ router })', () => {
|
||||
} as unknown as Workflow);
|
||||
vi.mocked(workflowHelpers).getWorkflowDataToSave.mockResolvedValue({
|
||||
nodes: [],
|
||||
} as unknown as IWorkflowData);
|
||||
} as unknown as WorkflowData);
|
||||
vi.mocked(workflowHelpers).executeData.mockResolvedValue({
|
||||
data: {},
|
||||
node: {},
|
||||
@@ -496,7 +497,7 @@ describe('useRunWorkflow({ router })', () => {
|
||||
mock<Workflow>({ getChildNodes: vi.fn().mockReturnValue([]) }),
|
||||
);
|
||||
vi.mocked(workflowHelpers).getWorkflowDataToSave.mockResolvedValue(
|
||||
mock<IWorkflowData>({ nodes: [] }),
|
||||
mock<WorkflowData>({ nodes: [] }),
|
||||
);
|
||||
|
||||
const { runWorkflow } = composable;
|
||||
@@ -527,7 +528,7 @@ describe('useRunWorkflow({ router })', () => {
|
||||
}),
|
||||
);
|
||||
vi.mocked(workflowHelpers).getWorkflowDataToSave.mockResolvedValue(
|
||||
mock<IWorkflowData>({ nodes: [] }),
|
||||
mock<WorkflowData>({ nodes: [] }),
|
||||
);
|
||||
|
||||
const { runWorkflow } = composable;
|
||||
@@ -566,7 +567,7 @@ describe('useRunWorkflow({ router })', () => {
|
||||
}),
|
||||
);
|
||||
vi.mocked(workflowHelpers).getWorkflowDataToSave.mockResolvedValue(
|
||||
mock<IWorkflowData>({ nodes: [] }),
|
||||
mock<WorkflowData>({ nodes: [] }),
|
||||
);
|
||||
|
||||
const { runWorkflow } = composable;
|
||||
@@ -594,7 +595,7 @@ describe('useRunWorkflow({ router })', () => {
|
||||
mock<Workflow>({ getChildNodes: vi.fn().mockReturnValue([]) }),
|
||||
);
|
||||
vi.mocked(workflowHelpers).getWorkflowDataToSave.mockResolvedValue(
|
||||
mock<IWorkflowData>({ nodes: [] }),
|
||||
mock<WorkflowData>({ nodes: [] }),
|
||||
);
|
||||
|
||||
// ACT
|
||||
@@ -625,7 +626,7 @@ describe('useRunWorkflow({ router })', () => {
|
||||
vi.mocked(workflowsStore).nodesIssuesExist = false;
|
||||
vi.mocked(workflowHelpers).getCurrentWorkflow.mockReturnValue(workflow);
|
||||
vi.mocked(workflowHelpers).getWorkflowDataToSave.mockResolvedValue(
|
||||
mock<IWorkflowData>({ id: 'workflowId', nodes: [] }),
|
||||
mock<WorkflowData>({ id: 'workflowId', nodes: [] }),
|
||||
);
|
||||
vi.mocked(workflowsStore).getWorkflowRunData = mockRunData;
|
||||
|
||||
@@ -738,7 +739,7 @@ describe('useRunWorkflow({ router })', () => {
|
||||
vi.mocked(workflowsStore).nodesIssuesExist = false;
|
||||
vi.mocked(workflowHelpers).getCurrentWorkflow.mockReturnValue(workflow);
|
||||
vi.mocked(workflowHelpers).getWorkflowDataToSave.mockResolvedValue(
|
||||
mock<IWorkflowData>({ id: 'workflowId', nodes: [] }),
|
||||
mock<WorkflowData>({ id: 'workflowId', nodes: [] }),
|
||||
);
|
||||
vi.mocked(workflowsStore).getWorkflowRunData = mockRunData;
|
||||
|
||||
@@ -767,7 +768,7 @@ describe('useRunWorkflow({ router })', () => {
|
||||
vi.mocked(workflowsStore).nodesIssuesExist = false;
|
||||
vi.mocked(workflowHelpers).getCurrentWorkflow.mockReturnValue(workflow);
|
||||
vi.mocked(workflowHelpers).getWorkflowDataToSave.mockResolvedValue(
|
||||
mock<IWorkflowData>({ id: 'workflowId', nodes: [] }),
|
||||
mock<WorkflowData>({ id: 'workflowId', nodes: [] }),
|
||||
);
|
||||
vi.mocked(workflowsStore).getWorkflowRunData = mockRunData;
|
||||
|
||||
@@ -789,7 +790,7 @@ describe('useRunWorkflow({ router })', () => {
|
||||
vi.mocked(workflowHelpers).getWorkflowDataToSave.mockResolvedValue({
|
||||
id: workflow.id,
|
||||
nodes: [],
|
||||
} as unknown as IWorkflowData);
|
||||
} as unknown as WorkflowData);
|
||||
|
||||
// Simulate failed execution start
|
||||
vi.mocked(workflowsStore).runWorkflow.mockRejectedValueOnce(new Error());
|
||||
@@ -915,7 +916,7 @@ describe('useRunWorkflow({ router })', () => {
|
||||
vi.mocked(workflowHelpers).getWorkflowDataToSave.mockResolvedValue({
|
||||
id: 'workflowId',
|
||||
nodes: [],
|
||||
} as unknown as IWorkflowData);
|
||||
} as unknown as WorkflowData);
|
||||
|
||||
await runWorkflowComposable.runEntireWorkflow('main', 'foo');
|
||||
|
||||
|
||||
@@ -17,7 +17,8 @@ import { VIEWS, WORKFLOW_EXTRACTION_NAME_MODAL_KEY } from '@/constants';
|
||||
import { useHistoryStore } from '@/stores/history.store';
|
||||
import { useCanvasOperations } from './useCanvasOperations';
|
||||
|
||||
import type { AddedNode, INodeUi, IWorkflowDataCreate, IWorkflowDb } from '@/Interface';
|
||||
import type { AddedNode, INodeUi, IWorkflowDb } from '@/Interface';
|
||||
import type { WorkflowDataCreate } from '@n8n/rest-api-client/api/workflows';
|
||||
import { useI18n } from '@n8n/i18n';
|
||||
import { PUSH_NODES_OFFSET } from '@/utils/nodeViewUtils';
|
||||
import { useUIStore } from '@/stores/ui.store';
|
||||
@@ -128,7 +129,7 @@ export function useWorkflowExtraction() {
|
||||
selectionChildrenVariables: Map<string, string>,
|
||||
startNodeName: string,
|
||||
returnNodeName: string,
|
||||
): IWorkflowDataCreate {
|
||||
): WorkflowDataCreate {
|
||||
const newConnections = Object.fromEntries(
|
||||
Object.entries(connections).filter(([k]) => nodes.some((x) => x.name === k)),
|
||||
);
|
||||
@@ -253,7 +254,7 @@ export function useWorkflowExtraction() {
|
||||
return [summedUp[0] / summedUp[2], summedUp[1] / summedUp[2]];
|
||||
}
|
||||
|
||||
async function tryCreateWorkflow(workflowData: IWorkflowDataCreate): Promise<IWorkflowDb | null> {
|
||||
async function tryCreateWorkflow(workflowData: WorkflowDataCreate): Promise<IWorkflowDb | null> {
|
||||
try {
|
||||
const createdWorkflow = await workflowsStore.createNewWorkflow(workflowData);
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { IExecutionResponse, IWorkflowData, IWorkflowDb } from '@/Interface';
|
||||
import type { IExecutionResponse, IWorkflowDb } from '@/Interface';
|
||||
import type { WorkflowData } from '@n8n/rest-api-client/api/workflows';
|
||||
import { useWorkflowHelpers } from '@/composables/useWorkflowHelpers';
|
||||
import { createTestingPinia } from '@pinia/testing';
|
||||
import { setActivePinia } from 'pinia';
|
||||
@@ -358,7 +359,7 @@ describe('useWorkflowHelpers', () => {
|
||||
uiStore.stateIsDirty = true;
|
||||
vi.spyOn(workflowHelpers, 'getWorkflowDataToSave').mockResolvedValue({
|
||||
nodes: [],
|
||||
} as unknown as IWorkflowData);
|
||||
} as unknown as WorkflowData);
|
||||
expect(await workflowHelpers.checkConflictingWebhooks('12345')).toEqual(null);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -27,14 +27,13 @@ import type {
|
||||
ICredentialsResponse,
|
||||
INodeTypesMaxCount,
|
||||
INodeUi,
|
||||
ITag,
|
||||
IWorkflowData,
|
||||
IWorkflowDataUpdate,
|
||||
IWorkflowDb,
|
||||
TargetItem,
|
||||
WorkflowTitleStatus,
|
||||
XYPosition,
|
||||
} from '@/Interface';
|
||||
import type { ITag } from '@n8n/rest-api-client/api/tags';
|
||||
import type { WorkflowData, WorkflowDataUpdate } from '@n8n/rest-api-client/api/workflows';
|
||||
|
||||
import { useNodeHelpers } from '@/composables/useNodeHelpers';
|
||||
|
||||
@@ -510,7 +509,7 @@ export function useWorkflowHelpers() {
|
||||
nodes.push(nodeData);
|
||||
}
|
||||
|
||||
const data: IWorkflowData = {
|
||||
const data: WorkflowData = {
|
||||
name: workflowsStore.workflowName,
|
||||
nodes,
|
||||
pinData: workflowsStore.pinnedWorkflowData,
|
||||
@@ -762,7 +761,7 @@ export function useWorkflowHelpers() {
|
||||
{ workflowId, active }: { workflowId: string; active?: boolean },
|
||||
partialData = false,
|
||||
) {
|
||||
let data: IWorkflowDataUpdate = {};
|
||||
let data: WorkflowDataUpdate = {};
|
||||
|
||||
const isCurrentWorkflow = workflowId === workflowsStore.workflowId;
|
||||
if (isCurrentWorkflow) {
|
||||
@@ -796,7 +795,7 @@ export function useWorkflowHelpers() {
|
||||
// Updates the position of all the nodes that the top-left node
|
||||
// is at the given position
|
||||
function updateNodePositions(
|
||||
workflowData: IWorkflowData | IWorkflowDataUpdate,
|
||||
workflowData: WorkflowData | WorkflowDataUpdate,
|
||||
position: XYPosition,
|
||||
): void {
|
||||
if (workflowData.nodes === undefined) {
|
||||
@@ -827,7 +826,7 @@ export function useWorkflowHelpers() {
|
||||
}
|
||||
|
||||
function removeForeignCredentialsFromWorkflow(
|
||||
workflow: IWorkflowData | IWorkflowDataUpdate,
|
||||
workflow: WorkflowData | WorkflowDataUpdate,
|
||||
usableCredentials: ICredentialsResponse[],
|
||||
): void {
|
||||
(workflow.nodes ?? []).forEach((node: INode) => {
|
||||
|
||||
@@ -6,7 +6,7 @@ import { createTestingPinia } from '@pinia/testing';
|
||||
import { setActivePinia } from 'pinia';
|
||||
import { useNpsSurveyStore } from '@/stores/npsSurvey.store';
|
||||
import { useWorkflowsStore } from '@/stores/workflows.store';
|
||||
import type { IWorkflowDataUpdate } from '@/Interface';
|
||||
import type { WorkflowDataUpdate } from '@n8n/rest-api-client/api/workflows';
|
||||
import { mockedStore } from '@/__tests__/utils';
|
||||
import { createTestNode, createTestWorkflow, mockNodeTypeDescription } from '@/__tests__/mocks';
|
||||
import { CHAT_TRIGGER_NODE_TYPE } from 'n8n-workflow';
|
||||
@@ -22,7 +22,7 @@ vi.mock('@/composables/useMessage', () => {
|
||||
};
|
||||
});
|
||||
|
||||
const getDuplicateTestWorkflow = (): IWorkflowDataUpdate => ({
|
||||
const getDuplicateTestWorkflow = (): WorkflowDataUpdate => ({
|
||||
name: 'Duplicate webhook test',
|
||||
active: false,
|
||||
nodes: [
|
||||
|
||||
@@ -15,13 +15,9 @@ import { useWorkflowHelpers } from '@/composables/useWorkflowHelpers';
|
||||
import { useWorkflowsStore } from '@/stores/workflows.store';
|
||||
import { useSourceControlStore } from '@/stores/sourceControl.store';
|
||||
import { useCanvasStore } from '@/stores/canvas.store';
|
||||
import type {
|
||||
ITag,
|
||||
IUpdateInformation,
|
||||
IWorkflowDataCreate,
|
||||
IWorkflowDataUpdate,
|
||||
NotificationOptions,
|
||||
} from '@/Interface';
|
||||
import type { IUpdateInformation, NotificationOptions } from '@/Interface';
|
||||
import type { ITag } from '@n8n/rest-api-client/api/tags';
|
||||
import type { WorkflowDataCreate, WorkflowDataUpdate } from '@n8n/rest-api-client/api/workflows';
|
||||
import type { IDataObject, INode, IWorkflowSettings } from 'n8n-workflow';
|
||||
import { useNodeTypesStore } from '@/stores/nodeTypes.store';
|
||||
import { useToast } from './useToast';
|
||||
@@ -134,7 +130,7 @@ export function useWorkflowSaving({ router }: { router: ReturnType<typeof useRou
|
||||
|
||||
async function getWorkflowDeactivationInfo(
|
||||
workflowId: string,
|
||||
request: IWorkflowDataUpdate,
|
||||
request: WorkflowDataUpdate,
|
||||
): Promise<Partial<NotificationOptions> | undefined> {
|
||||
const missingActivatableTriggerNode =
|
||||
request.nodes !== undefined && !request.nodes.some(isNodeActivatable);
|
||||
@@ -187,7 +183,7 @@ export function useWorkflowSaving({ router }: { router: ReturnType<typeof useRou
|
||||
}
|
||||
uiStore.addActiveAction('workflowSaving');
|
||||
|
||||
const workflowDataRequest: IWorkflowDataUpdate = await getWorkflowDataToSave();
|
||||
const workflowDataRequest: WorkflowDataUpdate = await getWorkflowDataToSave();
|
||||
// This can happen if the user has another workflow in the browser history and navigates
|
||||
// via the browser back button, encountering our warning dialog with the new route already set
|
||||
if (workflowDataRequest.id !== currentWorkflow) {
|
||||
@@ -306,14 +302,14 @@ export function useWorkflowSaving({ router }: { router: ReturnType<typeof useRou
|
||||
openInNewWindow?: boolean;
|
||||
resetNodeIds?: boolean;
|
||||
parentFolderId?: string;
|
||||
data?: IWorkflowDataCreate;
|
||||
data?: WorkflowDataCreate;
|
||||
} = {},
|
||||
redirect = true,
|
||||
): Promise<boolean> {
|
||||
try {
|
||||
uiStore.addActiveAction('workflowSaving');
|
||||
|
||||
const workflowDataRequest: IWorkflowDataCreate = data || (await getWorkflowDataToSave());
|
||||
const workflowDataRequest: WorkflowDataCreate = data || (await getWorkflowDataToSave());
|
||||
const changedNodes = {} as IDataObject;
|
||||
|
||||
if (resetNodeIds) {
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { NodeConnectionTypes } from 'n8n-workflow';
|
||||
import type { INodeUi, IWorkflowDataCreate } from './Interface';
|
||||
import type { INodeUi } from './Interface';
|
||||
import type { WorkflowDataCreate } from '@n8n/rest-api-client/api/workflows';
|
||||
|
||||
export const SAMPLE_SUBWORKFLOW_TRIGGER_ID = 'c055762a-8fe7-4141-a639-df2372f30060';
|
||||
export const SAMPLE_SUBWORKFLOW_WORKFLOW: IWorkflowDataCreate = {
|
||||
export const SAMPLE_SUBWORKFLOW_WORKFLOW: WorkflowDataCreate = {
|
||||
name: 'My Sub-Workflow',
|
||||
nodes: [
|
||||
{
|
||||
@@ -40,7 +41,7 @@ export const SAMPLE_SUBWORKFLOW_WORKFLOW: IWorkflowDataCreate = {
|
||||
pinData: {},
|
||||
};
|
||||
|
||||
export const SAMPLE_EVALUATION_WORKFLOW: IWorkflowDataCreate = {
|
||||
export const SAMPLE_EVALUATION_WORKFLOW: WorkflowDataCreate = {
|
||||
name: 'My Evaluation Sub-Workflow',
|
||||
nodes: [
|
||||
{
|
||||
|
||||
@@ -9,7 +9,7 @@ import type {
|
||||
import * as eventsApi from '@n8n/rest-api-client/api/events';
|
||||
import * as settingsApi from '@n8n/rest-api-client/api/settings';
|
||||
import * as moduleSettingsApi from '@n8n/rest-api-client/api/module-settings';
|
||||
import { testHealthEndpoint } from '@/api/templates';
|
||||
import { testHealthEndpoint } from '@n8n/rest-api-client/api/templates';
|
||||
import {
|
||||
INSECURE_CONNECTION_WARNING,
|
||||
LOCAL_STORAGE_EXPERIMENTAL_DOCKED_NODE_SETTINGS,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { createTagsApi } from '@/api/tags';
|
||||
import { STORES } from '@n8n/stores';
|
||||
import type { ITag } from '@/Interface';
|
||||
import type { ITag } from '@n8n/rest-api-client/api/tags';
|
||||
import { defineStore } from 'pinia';
|
||||
import { useRootStore } from '@n8n/stores/useRootStore';
|
||||
import { computed, ref } from 'vue';
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import { TEMPLATES_URLS } from '@/constants';
|
||||
import { STORES } from '@n8n/stores';
|
||||
import type { INodeUi } from '@/Interface';
|
||||
import { useSettingsStore } from './settings.store';
|
||||
import * as templatesApi from '@n8n/rest-api-client/api/templates';
|
||||
import type {
|
||||
INodeUi,
|
||||
ITemplatesCategory,
|
||||
ITemplatesCollection,
|
||||
ITemplatesCollectionFull,
|
||||
@@ -10,15 +12,35 @@ import type {
|
||||
ITemplatesWorkflow,
|
||||
ITemplatesWorkflowFull,
|
||||
IWorkflowTemplate,
|
||||
} from '@/Interface';
|
||||
import { useSettingsStore } from './settings.store';
|
||||
import * as templatesApi from '@/api/templates';
|
||||
} from '@n8n/rest-api-client/api/templates';
|
||||
import { getNodesWithNormalizedPosition } from '@/utils/nodeViewUtils';
|
||||
import { useRootStore } from '@n8n/stores/useRootStore';
|
||||
import { useUsersStore } from './users.store';
|
||||
import { useWorkflowsStore } from './workflows.store';
|
||||
import { computed, ref } from 'vue';
|
||||
|
||||
export interface ITemplateState {
|
||||
categories: ITemplatesCategory[];
|
||||
collections: { [id: string]: ITemplatesCollection };
|
||||
workflows: { [id: string]: ITemplatesWorkflow | ITemplatesWorkflowFull };
|
||||
workflowSearches: {
|
||||
[search: string]: {
|
||||
workflowIds: string[];
|
||||
totalWorkflows: number;
|
||||
loadingMore?: boolean;
|
||||
categories?: ITemplatesCategory[];
|
||||
};
|
||||
};
|
||||
collectionSearches: {
|
||||
[search: string]: {
|
||||
collectionIds: string[];
|
||||
};
|
||||
};
|
||||
currentSessionId: string;
|
||||
previousSessionId: string;
|
||||
currentN8nPath: string;
|
||||
}
|
||||
|
||||
const TEMPLATES_PAGE_SIZE = 20;
|
||||
|
||||
function getSearchKey(query: ITemplatesQuery): string {
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { computed } from 'vue';
|
||||
import { defineStore } from 'pinia';
|
||||
import { saveAs } from 'file-saver';
|
||||
import type { IWorkflowDataUpdate, IWorkflowDb } from '@/Interface';
|
||||
import type { IWorkflowDb } from '@/Interface';
|
||||
import type { WorkflowDataUpdate } from '@n8n/rest-api-client/api/workflows';
|
||||
import type {
|
||||
WorkflowHistory,
|
||||
WorkflowVersion,
|
||||
@@ -68,7 +69,7 @@ export const useWorkflowHistoryStore = defineStore('workflowHistory', () => {
|
||||
const newWorkflow = await getNewWorkflow(rootStore.restApiContext, {
|
||||
name: `${name} (${data.formattedCreatedAt})`,
|
||||
});
|
||||
const newWorkflowData: IWorkflowDataUpdate = {
|
||||
const newWorkflowData: WorkflowDataUpdate = {
|
||||
nodes,
|
||||
connections,
|
||||
name: newWorkflow.name,
|
||||
@@ -83,7 +84,7 @@ export const useWorkflowHistoryStore = defineStore('workflowHistory', () => {
|
||||
): Promise<IWorkflowDb> => {
|
||||
const workflowVersion = await getWorkflowVersion(workflowId, workflowVersionId);
|
||||
const { connections, nodes } = workflowVersion;
|
||||
const updateData: IWorkflowDataUpdate = { connections, nodes };
|
||||
const updateData: WorkflowDataUpdate = { connections, nodes };
|
||||
|
||||
if (shouldDeactivate) {
|
||||
updateData.active = false;
|
||||
|
||||
@@ -23,16 +23,18 @@ import type {
|
||||
IStartRunData,
|
||||
IUpdateInformation,
|
||||
IUsedCredential,
|
||||
IWorkflowDataUpdate,
|
||||
IWorkflowDb,
|
||||
IWorkflowsMap,
|
||||
NodeMetadataMap,
|
||||
WorkflowMetadata,
|
||||
IExecutionFlattedResponse,
|
||||
IWorkflowTemplateNode,
|
||||
IWorkflowDataCreate,
|
||||
WorkflowListResource,
|
||||
} from '@/Interface';
|
||||
import type { IWorkflowTemplateNode } from '@n8n/rest-api-client/api/templates';
|
||||
import type {
|
||||
WorkflowMetadata,
|
||||
WorkflowDataCreate,
|
||||
WorkflowDataUpdate,
|
||||
} from '@n8n/rest-api-client/api/workflows';
|
||||
import { defineStore } from 'pinia';
|
||||
import type {
|
||||
IConnection,
|
||||
@@ -1681,7 +1683,7 @@ export const useWorkflowsStore = defineStore(STORES.WORKFLOWS, () => {
|
||||
* Ensures that the new workflow is not active upon creation.
|
||||
* If the project ID is not provided in the data, it assigns the current project ID from the project store.
|
||||
*/
|
||||
async function createNewWorkflow(sendData: IWorkflowDataCreate): Promise<IWorkflowDb> {
|
||||
async function createNewWorkflow(sendData: WorkflowDataCreate): Promise<IWorkflowDb> {
|
||||
// make sure that the new ones are not active
|
||||
sendData.active = false;
|
||||
|
||||
@@ -1714,7 +1716,7 @@ export const useWorkflowsStore = defineStore(STORES.WORKFLOWS, () => {
|
||||
|
||||
async function updateWorkflow(
|
||||
id: string,
|
||||
data: IWorkflowDataUpdate,
|
||||
data: WorkflowDataUpdate,
|
||||
forceSave = false,
|
||||
): Promise<IWorkflowDb> {
|
||||
if (data.settings === null) {
|
||||
|
||||
@@ -17,9 +17,9 @@ import type {
|
||||
INodeUpdatePropertiesInformation,
|
||||
IPersonalizationLatestVersion,
|
||||
IWorkflowDb,
|
||||
IWorkflowTemplateNode,
|
||||
NodeFilterType,
|
||||
} from '@/Interface';
|
||||
import type { IWorkflowTemplateNode } from '@n8n/rest-api-client/api/templates';
|
||||
import type { ComponentPublicInstance } from 'vue';
|
||||
import type { useWebhooksStore } from '@/stores/webhooks.store';
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@ import type {
|
||||
AppliedThemeOption,
|
||||
INodeUi,
|
||||
INodeUpdatePropertiesInformation,
|
||||
ITemplatesNode,
|
||||
NodeAuthenticationOption,
|
||||
} from '@/Interface';
|
||||
import type { ITemplatesNode } from '@n8n/rest-api-client/api/templates';
|
||||
import {
|
||||
CORE_NODES_CATEGORY,
|
||||
MAIN_AUTH_FIELD_NAME,
|
||||
|
||||
@@ -5,7 +5,7 @@ import { vi } from 'vitest';
|
||||
import { mock } from 'vitest-mock-extended';
|
||||
|
||||
import { VIEWS } from '@/constants';
|
||||
import type { ITemplatesWorkflowFull } from '@/Interface';
|
||||
import type { ITemplatesWorkflowFull } from '@n8n/rest-api-client/api/templates';
|
||||
import { Telemetry } from '@/plugins/telemetry';
|
||||
import type { NodeTypesStore } from '@/stores/nodeTypes.store';
|
||||
import { useNodeTypesStore } from '@/stores/nodeTypes.store';
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
import type {
|
||||
INodeUi,
|
||||
ITemplatesWorkflowFull,
|
||||
IWorkflowData,
|
||||
IWorkflowTemplate,
|
||||
} from '@/Interface';
|
||||
import type { INodeUi } from '@/Interface';
|
||||
import type { ITemplatesWorkflowFull, IWorkflowTemplate } from '@n8n/rest-api-client/api/templates';
|
||||
import type { WorkflowData } from '@n8n/rest-api-client/api/workflows';
|
||||
import { getNewWorkflow } from '@/api/workflows';
|
||||
import { VIEWS } from '@/constants';
|
||||
import type { useRootStore } from '@n8n/stores/useRootStore';
|
||||
@@ -45,7 +42,7 @@ export async function createWorkflowFromTemplate(opts: {
|
||||
const nodes = getNodesWithNormalizedPosition(nodesWithCreds) as INodeUi[];
|
||||
const connections = template.workflow.connections;
|
||||
|
||||
const workflowToCreate: IWorkflowData = {
|
||||
const workflowToCreate: WorkflowData = {
|
||||
name: workflowData.name,
|
||||
nodes,
|
||||
connections,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { mock } from 'vitest-mock-extended';
|
||||
import type { IWorkflowTemplateNode } from '@/Interface';
|
||||
import type { IWorkflowTemplateNode } from '@n8n/rest-api-client/api/templates';
|
||||
import {
|
||||
keyFromCredentialTypeAndName,
|
||||
replaceAllTemplateNodeCredentials,
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
import type { IWorkflowTemplateNode, IWorkflowTemplateNodeCredentials } from '@/Interface';
|
||||
import type {
|
||||
IWorkflowTemplateNode,
|
||||
IWorkflowTemplateNodeCredentials,
|
||||
} from '@n8n/rest-api-client/api/templates';
|
||||
|
||||
import type { NodeTypeProvider } from '@/utils/nodeTypes/nodeTypeTransforms';
|
||||
import { getNodeTypeDisplayableCredentials } from '@/utils/nodes/nodeTransforms';
|
||||
import type { NormalizedTemplateNodeCredentials } from '@/utils/templates/templateTypes';
|
||||
|
||||
@@ -2,7 +2,7 @@ import type {
|
||||
ITemplatesCollection,
|
||||
ITemplatesCollectionFull,
|
||||
ITemplatesWorkflow,
|
||||
} from '@/Interface';
|
||||
} from '@n8n/rest-api-client/api/templates';
|
||||
|
||||
export function isTemplatesWorkflow(
|
||||
template: ITemplatesWorkflow | ITemplatesCollection | ITemplatesCollectionFull | null,
|
||||
|
||||
@@ -27,15 +27,15 @@ import type {
|
||||
IExecutionResponse,
|
||||
INodeUi,
|
||||
IUpdateInformation,
|
||||
IWorkflowDataUpdate,
|
||||
IWorkflowDb,
|
||||
IWorkflowTemplate,
|
||||
NodeCreatorOpenSource,
|
||||
NodeFilterType,
|
||||
ToggleNodeCreatorOptions,
|
||||
WorkflowDataWithTemplateId,
|
||||
XYPosition,
|
||||
} from '@/Interface';
|
||||
import type { IWorkflowTemplate } from '@n8n/rest-api-client/api/templates';
|
||||
import type { WorkflowDataUpdate } from '@n8n/rest-api-client/api/workflows';
|
||||
import type {
|
||||
Connection,
|
||||
Dimensions,
|
||||
@@ -769,7 +769,7 @@ async function onClipboardPaste(plainTextData: string): Promise<void> {
|
||||
return;
|
||||
}
|
||||
|
||||
let workflowData: IWorkflowDataUpdate | null | undefined = null;
|
||||
let workflowData: WorkflowDataUpdate | null | undefined = null;
|
||||
|
||||
// Check if it is an URL which could contain workflow data
|
||||
if (plainTextData.match(VALID_WORKFLOW_IMPORT_URL_REGEX)) {
|
||||
@@ -796,7 +796,7 @@ async function onClipboardPaste(plainTextData: string): Promise<void> {
|
||||
workflowData = await fetchWorkflowDataFromUrl(plainTextData);
|
||||
} else {
|
||||
// Pasted data is possible workflow data
|
||||
workflowData = jsonParse<IWorkflowDataUpdate | null>(plainTextData, { fallbackValue: null });
|
||||
workflowData = jsonParse<WorkflowDataUpdate | null>(plainTextData, { fallbackValue: null });
|
||||
}
|
||||
|
||||
if (!workflowData) {
|
||||
@@ -1048,7 +1048,7 @@ function onRevertDeleteConnection({ connection }: { connection: [IConnection, IC
|
||||
* Import / Export
|
||||
*/
|
||||
|
||||
async function importWorkflowExact({ workflow: workflowData }: { workflow: IWorkflowDataUpdate }) {
|
||||
async function importWorkflowExact({ workflow: workflowData }: { workflow: WorkflowDataUpdate }) {
|
||||
if (!workflowData.nodes || !workflowData.connections) {
|
||||
throw new Error('Invalid workflow object');
|
||||
}
|
||||
@@ -1066,7 +1066,7 @@ async function importWorkflowExact({ workflow: workflowData }: { workflow: IWork
|
||||
}
|
||||
|
||||
async function onImportWorkflowDataEvent(data: IDataObject) {
|
||||
const workflowData = data.data as IWorkflowDataUpdate;
|
||||
const workflowData = data.data as WorkflowDataUpdate;
|
||||
await importWorkflowData(workflowData, 'file', {
|
||||
viewport: viewportBoundaries.value,
|
||||
});
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { faker } from '@faker-js/faker/locale/en';
|
||||
import type { ICredentialsResponse } from '@/Interface';
|
||||
import type {
|
||||
ICredentialsResponse,
|
||||
ITemplatesWorkflowFull,
|
||||
IWorkflowTemplateNode,
|
||||
} from '@/Interface';
|
||||
} from '@n8n/rest-api-client/api/templates';
|
||||
|
||||
export const newFullOneNodeTemplate = (node: IWorkflowTemplateNode): ITemplatesWorkflowFull => ({
|
||||
full: true,
|
||||
|
||||
@@ -3,11 +3,11 @@ import { createTestingPinia } from '@pinia/testing';
|
||||
import { mock } from 'vitest-mock-extended';
|
||||
import type { ICredentialType } from 'n8n-workflow';
|
||||
|
||||
import type { ICredentialsResponse } from '@/Interface';
|
||||
import type {
|
||||
ICredentialsResponse,
|
||||
ITemplatesWorkflowFull,
|
||||
IWorkflowTemplateNode,
|
||||
} from '@/Interface';
|
||||
} from '@n8n/rest-api-client/api/templates';
|
||||
import { useTemplatesStore } from '@/stores/templates.store';
|
||||
import { keyFromCredentialTypeAndName } from '@/utils/templates/templateTransforms';
|
||||
import { useSetupTemplateStore } from '@/views/SetupWorkflowFromTemplateView/setupTemplate.store';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { mock } from 'vitest-mock-extended';
|
||||
import type { IWorkflowTemplateNode } from '@/Interface';
|
||||
import type { IWorkflowTemplateNode } from '@n8n/rest-api-client/api/templates';
|
||||
import { keyFromCredentialTypeAndName } from '@/utils/templates/templateTransforms';
|
||||
import type { IWorkflowTemplateNodeWithCredentials } from '@/utils/templates/templateTransforms';
|
||||
import type { CredentialUsages } from '@/views/SetupWorkflowFromTemplateView/useCredentialSetupState';
|
||||
|
||||
@@ -3,7 +3,7 @@ import { computed, onMounted, ref, watch } from 'vue';
|
||||
import TemplateDetails from '@/components/TemplateDetails.vue';
|
||||
import TemplateList from '@/components/TemplateList.vue';
|
||||
import TemplatesView from './TemplatesView.vue';
|
||||
import type { ITemplatesWorkflow } from '@/Interface';
|
||||
import type { ITemplatesWorkflow } from '@n8n/rest-api-client/api/templates';
|
||||
import { VIEWS } from '@/constants';
|
||||
import { useTemplatesStore } from '@/stores/templates.store';
|
||||
import { useTemplateWorkflow } from '@/utils/templates/templateActions';
|
||||
|
||||
@@ -5,7 +5,7 @@ import TemplateFilters from '@/components/TemplateFilters.vue';
|
||||
import TemplateList from '@/components/TemplateList.vue';
|
||||
import TemplatesView from '@/views/TemplatesView.vue';
|
||||
|
||||
import type { ITemplatesCategory } from '@/Interface';
|
||||
import type { ITemplatesCategory } from '@n8n/rest-api-client/api/templates';
|
||||
import type { IDataObject } from 'n8n-workflow';
|
||||
import { CREATOR_HUB_URL, VIEWS } from '@/constants';
|
||||
import { useSettingsStore } from '@/stores/settings.store';
|
||||
|
||||
Reference in New Issue
Block a user