Skip to content

Commit

Permalink
feat(editor): Add template Id to workflow metadata (#8088)
Browse files Browse the repository at this point in the history
## Summary
Adding a link between the workflow and the template it originated from
by saving `templateId` in the workflow metadata

## Related tickets and issues
ADO-1537

## Review / Merge checklist
- [x] PR title and summary are descriptive. **Remember, the title
automatically goes into the changelog. Use `(no-changelog)` otherwise.**
([conventions](https://github.com/n8n-io/n8n/blob/master/.github/pull_request_title_conventions.md))
- [ ] [Docs updated](https://github.com/n8n-io/n8n-docs) or follow-up
ticket created.
- [x] Tests included.
> A bug is not considered fixed, unless a test is added to prevent it
from happening again.
   > A feature is not complete without tests.
MiloradFilipovic authored Dec 22, 2023

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent c83d9f4 commit 517b050
Showing 7 changed files with 48 additions and 5 deletions.
25 changes: 24 additions & 1 deletion cypress/e2e/29-templates.cy.ts
Original file line number Diff line number Diff line change
@@ -29,12 +29,35 @@ describe('Templates', () => {
cy.url().then(($url) => {
expect($url).to.include('/workflow/new?templateId=1234');
});

workflowPage.getters.canvasNodes().should('have.length', 4);
workflowPage.getters.stickies().should('have.length', 1);
workflowPage.actions.shouldHaveWorkflowName(OnboardingWorkflow.name);
});

it('should save template id with the workflow', () => {
cy.visit(templatesPage.url);
templatesPage.getters.firstTemplateCard().click();
cy.url().should('include', '/templates/');

cy.url().then(($url) => {
const templateId = $url.split('/').pop();

templatesPage.getters.useTemplateButton().click();
cy.url().should('include', '/workflow/new');
workflowPage.actions.saveWorkflowOnButtonClick();

workflowPage.actions.selectAll();
workflowPage.actions.hitCopy();

cy.grantBrowserPermissions('clipboardReadWrite', 'clipboardSanitizedWrite');
// Check workflow JSON by copying it to clipboard
cy.readClipboard().then((workflowJSON) => {
expect(workflowJSON).to.contain(`"templateId": "${templateId}"`);
});
});
});

it('can open template with images and hides workflow screenshots', () => {
templateWorkflowPage.actions.openTemplate(WorkflowTemplate);

4 changes: 3 additions & 1 deletion cypress/pages/templates.ts
Original file line number Diff line number Diff line change
@@ -4,7 +4,9 @@ export class TemplatesPage extends BasePage {
url = '/templates';

getters = {
useTemplateButton: () => cy.get('[data-testid="use-template-button"]'),
useTemplateButton: () => cy.getByTestId('use-template-button'),
templateCards: () => cy.getByTestId('template-card'),
firstTemplateCard: () => this.getters.templateCards().first(),
};

actions = {
7 changes: 4 additions & 3 deletions packages/editor-ui/src/Interface.ts
Original file line number Diff line number Diff line change
@@ -227,6 +227,7 @@ export interface IWorkflowData {
tags?: string[];
pinData?: IPinData;
versionId?: string;
meta?: WorkflowMetadata;
}

export interface IWorkflowDataUpdate {
@@ -243,9 +244,7 @@ export interface IWorkflowDataUpdate {
}

export interface IWorkflowToShare extends IWorkflowDataUpdate {
meta?: {
instanceId: string;
};
meta?: WorkflowMetadata;
}

export interface IWorkflowTemplateNode
@@ -273,6 +272,8 @@ export interface INewWorkflowData {

export interface WorkflowMetadata {
onboardingId?: string;
templateId?: string;
instanceId?: string;
}

// Almost identical to cli.Interfaces.ts
Original file line number Diff line number Diff line change
@@ -537,6 +537,7 @@ export default defineComponent({
const exportData: IWorkflowToShare = {
...data,
meta: {
...(this.workflowsStore.workflow.meta || {}),
instanceId: this.rootStore.instanceId,
},
tags: (tags || []).map((tagId) => {
1 change: 1 addition & 0 deletions packages/editor-ui/src/mixins/workflowHelpers.ts
Original file line number Diff line number Diff line change
@@ -656,6 +656,7 @@ export const workflowHelpers = defineComponent({
settings: this.workflowsStore.workflow.settings,
tags: this.workflowsStore.workflowTags,
versionId: this.workflowsStore.workflow.versionId,
meta: this.workflowsStore.workflow.meta,
};

const workflowId = this.workflowsStore.workflowId;
12 changes: 12 additions & 0 deletions packages/editor-ui/src/stores/workflows.store.ts
Original file line number Diff line number Diff line change
@@ -32,6 +32,7 @@ import type {
IWorkflowsMap,
WorkflowsState,
NodeMetadataMap,
WorkflowMetadata,
} from '@/Interface';
import { defineStore } from 'pinia';
import type {
@@ -656,6 +657,17 @@ export const useWorkflowsStore = defineStore(STORES.WORKFLOWS, {
};
},

setWorkflowMetadata(metadata: WorkflowMetadata | undefined): void {
this.workflow.meta = metadata;
},

addToWorkflowMetadata(data: Partial<WorkflowMetadata>): void {
this.workflow.meta = {
...this.workflow.meta,
...data,
};
},

setWorkflow(workflow: IWorkflowDb): void {
this.workflow = workflow;
this.workflow = {
3 changes: 3 additions & 0 deletions packages/editor-ui/src/views/NodeView.vue
Original file line number Diff line number Diff line change
@@ -1064,6 +1064,7 @@ export default defineComponent({

await this.addNodes(data.workflow.nodes, data.workflow.connections);
this.workflowData = (await this.workflowsStore.getNewWorkflowData(data.name)) || {};
this.workflowsStore.addToWorkflowMetadata({ templateId });
await this.$nextTick();
this.canvasStore.zoomToFit();
this.uiStore.stateIsDirty = true;
@@ -1089,6 +1090,7 @@ export default defineComponent({
this.workflowsStore.setWorkflowSettings(workflow.settings || {});
this.workflowsStore.setWorkflowPinData(workflow.pinData || {});
this.workflowsStore.setWorkflowVersionId(workflow.versionId);
this.workflowsStore.setWorkflowMetadata(workflow.meta);

if (workflow.ownedBy) {
this.workflowsEEStore.setWorkflowOwnedBy({
@@ -1585,6 +1587,7 @@ export default defineComponent({
void this.getNodesToSave(nodes).then((data) => {
const workflowToCopy: IWorkflowToShare = {
meta: {
...(this.workflowsStore.workflow.meta ?? {}),
instanceId: this.rootStore.instanceId,
},
...data,

0 comments on commit 517b050

Please sign in to comment.