diff --git a/cypress/e2e/7-workflow-actions.cy.ts b/cypress/e2e/7-workflow-actions.cy.ts index 0f6705bf34..2cf451b5ad 100644 --- a/cypress/e2e/7-workflow-actions.cy.ts +++ b/cypress/e2e/7-workflow-actions.cy.ts @@ -108,6 +108,23 @@ describe('Workflow Actions', () => { cy.wait('@saveWorkflow'); cy.wrap(null).then(() => expect(interceptCalledCount).to.eq(1)); }); + + it('should not save workflow twice when save is in progress', () => { + // This happens when users click save button from workflow name input + // In this case blur on the input saves the workflow and then click on the button saves it again + WorkflowPage.actions.visit(); + WorkflowPage.getters.workflowNameInput().invoke('val').then((oldName) => { + WorkflowPage.getters.workflowNameInputContainer().click(); + WorkflowPage.getters.workflowNameInput().type('{selectall}'); + WorkflowPage.getters.workflowNameInput().type('Test'); + WorkflowPage.getters.saveButton().click(); + WorkflowPage.getters.workflowNameInput().should('have.value', 'Test'); + cy.visit(WorkflowPages.url); + // There should be no workflow with the old name (duplicate save) + WorkflowPages.getters.workflowCards().contains(String(oldName)).should('not.exist'); + }); + }); + it('should copy nodes', () => { WorkflowPage.actions.addNodeToCanvas(SCHEDULE_TRIGGER_NODE_NAME); WorkflowPage.actions.addNodeToCanvas(CODE_NODE_NAME); diff --git a/packages/editor-ui/src/components/MainHeader/WorkflowDetails.vue b/packages/editor-ui/src/components/MainHeader/WorkflowDetails.vue index 8658b685e3..e8836c651f 100644 --- a/packages/editor-ui/src/components/MainHeader/WorkflowDetails.vue +++ b/packages/editor-ui/src/components/MainHeader/WorkflowDetails.vue @@ -388,6 +388,10 @@ export default defineComponent({ }, methods: { async onSaveButtonClick() { + // If the workflow is saving, do not allow another save + if (this.isWorkflowSaving) { + return; + } let currentId = undefined; if (this.currentWorkflowId !== PLACEHOLDER_EMPTY_WORKFLOW_ID) { currentId = this.currentWorkflowId; @@ -497,11 +501,12 @@ export default defineComponent({ cb(true); return; } - + this.uiStore.addActiveAction('workflowSaving'); const saved = await this.workflowHelpers.saveCurrentWorkflow({ name }); if (saved) { this.isNameEditEnabled = false; } + this.uiStore.removeActiveAction('workflowSaving'); cb(saved); }, async handleFileImport(): Promise {