feat(editor): Don't confirm archiving nonactive workflows (no-changelog) (#15182)

This commit is contained in:
Jaakko Husso
2025-05-08 21:33:50 +03:00
committed by GitHub
parent 077f4bf846
commit 374b2cf882
7 changed files with 143 additions and 46 deletions

View File

@@ -68,7 +68,6 @@ describe('Workflows', () => {
for (let i = 0; i < multipleWorkflowsCount + 1; i++) {
cy.getByTestId('workflow-card-actions').first().click();
WorkflowsPage.getters.workflowArchiveButton().click();
cy.get('button').contains('archive').click();
successToast().should('be.visible');
}
@@ -158,7 +157,6 @@ describe('Workflows', () => {
// Archive -> Unarchive -> Archive -> Delete on the first workflow
cy.getByTestId('workflow-card-actions').first().click();
WorkflowsPage.getters.workflowArchiveButton().click();
cy.get('button').contains('archive').click();
successToast().should('be.visible');
cy.getByTestId('workflow-card-actions').first().click();
@@ -167,7 +165,6 @@ describe('Workflows', () => {
cy.getByTestId('workflow-card-actions').first().click();
WorkflowsPage.getters.workflowArchiveButton().click();
cy.get('button').contains('archive').click();
successToast().should('be.visible');
cy.getByTestId('workflow-card-actions').first().click();

View File

@@ -267,7 +267,7 @@ describe('Workflow Actions', () => {
.should('have.class', 'is-disabled');
});
it('should archive workflow and then delete it', () => {
it('should archive nonactive workflow and then delete it', () => {
WorkflowPage.actions.saveWorkflowOnButtonClick();
WorkflowPage.getters.archivedTag().should('not.exist');
@@ -275,7 +275,6 @@ describe('Workflow Actions', () => {
WorkflowPage.getters.workflowMenu().should('be.visible');
WorkflowPage.getters.workflowMenu().click();
WorkflowPage.getters.workflowMenuItemArchive().click();
WorkflowPage.actions.acceptConfirmModal();
successToast().should('exist');
cy.url().should('include', WorkflowPages.url);
@@ -295,8 +294,11 @@ describe('Workflow Actions', () => {
cy.url().should('include', WorkflowPages.url);
});
it('should archive workflow and then unarchive it', () => {
it('should archive active workflow and then delete it', () => {
WorkflowPage.actions.addNodeToCanvas(SCHEDULE_TRIGGER_NODE_NAME);
WorkflowPage.actions.saveWorkflowOnButtonClick();
WorkflowPage.actions.activateWorkflow();
WorkflowPage.getters.isWorkflowActivated();
WorkflowPage.getters.archivedTag().should('not.exist');
// Archive the workflow
@@ -304,6 +306,35 @@ describe('Workflow Actions', () => {
WorkflowPage.getters.workflowMenu().click();
WorkflowPage.getters.workflowMenuItemArchive().click();
WorkflowPage.actions.acceptConfirmModal();
successToast().should('exist');
cy.url().should('include', WorkflowPages.url);
// Return back to the workflow
cy.go('back');
WorkflowPage.getters.archivedTag().should('be.visible');
WorkflowPage.getters.nodeCreatorPlusButton().should('not.exist');
WorkflowPage.getters.isWorkflowDeactivated();
// Delete the workflow
WorkflowPage.getters.workflowMenu().should('be.visible');
WorkflowPage.getters.workflowMenu().click();
WorkflowPage.getters.workflowMenuItemDelete().click();
WorkflowPage.actions.acceptConfirmModal();
successToast().should('exist');
cy.url().should('include', WorkflowPages.url);
});
it('should archive nonactive workflow and then unarchive it', () => {
WorkflowPage.actions.saveWorkflowOnButtonClick();
WorkflowPage.getters.archivedTag().should('not.exist');
// Archive the workflow
WorkflowPage.getters.workflowMenu().should('be.visible');
WorkflowPage.getters.workflowMenu().click();
WorkflowPage.getters.workflowMenuItemArchive().click();
successToast().should('exist');
cy.url().should('include', WorkflowPages.url);

View File

@@ -298,10 +298,38 @@ describe('WorkflowDetails', () => {
expect(queryByTestId('workflow-menu-item-unarchive')).not.toBeInTheDocument();
});
it("should call onWorkflowMenuSelect on 'Archive' option click", async () => {
it("should call onWorkflowMenuSelect on 'Archive' option click on nonactive workflow", async () => {
const { getByTestId } = renderComponent({
props: {
...workflow,
active: false,
readOnly: false,
isArchived: false,
scopes: ['workflow:delete'],
},
});
workflowsStore.archiveWorkflow.mockResolvedValue(undefined);
await userEvent.click(getByTestId('workflow-menu'));
await userEvent.click(getByTestId('workflow-menu-item-archive'));
expect(message.confirm).toHaveBeenCalledTimes(0);
expect(toast.showError).toHaveBeenCalledTimes(0);
expect(toast.showMessage).toHaveBeenCalledTimes(1);
expect(workflowsStore.archiveWorkflow).toHaveBeenCalledTimes(1);
expect(workflowsStore.archiveWorkflow).toHaveBeenCalledWith(workflow.id);
expect(router.push).toHaveBeenCalledTimes(1);
expect(router.push).toHaveBeenCalledWith({
name: VIEWS.WORKFLOWS,
});
});
it("should confirm onWorkflowMenuSelect on 'Archive' option click on active workflow", async () => {
const { getByTestId } = renderComponent({
props: {
...workflow,
active: true,
readOnly: false,
isArchived: false,
scopes: ['workflow:delete'],

View File

@@ -535,24 +535,26 @@ async function onWorkflowMenuSelect(action: WORKFLOW_MENU_ACTIONS): Promise<void
break;
}
case WORKFLOW_MENU_ACTIONS.ARCHIVE: {
const archiveConfirmed = await message.confirm(
locale.baseText('mainSidebar.confirmMessage.workflowArchive.message', {
interpolate: { workflowName: props.name },
}),
locale.baseText('mainSidebar.confirmMessage.workflowArchive.headline'),
{
type: 'warning',
confirmButtonText: locale.baseText(
'mainSidebar.confirmMessage.workflowArchive.confirmButtonText',
),
cancelButtonText: locale.baseText(
'mainSidebar.confirmMessage.workflowArchive.cancelButtonText',
),
},
);
if (props.active) {
const archiveConfirmed = await message.confirm(
locale.baseText('mainSidebar.confirmMessage.workflowArchive.message', {
interpolate: { workflowName: props.name },
}),
locale.baseText('mainSidebar.confirmMessage.workflowArchive.headline'),
{
type: 'warning',
confirmButtonText: locale.baseText(
'mainSidebar.confirmMessage.workflowArchive.confirmButtonText',
),
cancelButtonText: locale.baseText(
'mainSidebar.confirmMessage.workflowArchive.cancelButtonText',
),
},
);
if (archiveConfirmed !== MODAL_CONFIRM) {
return;
if (archiveConfirmed !== MODAL_CONFIRM) {
return;
}
}
try {

View File

@@ -202,9 +202,46 @@ describe('WorkflowCard', () => {
expect(actions).toHaveTextContent('Change owner');
});
it("should have 'Archive' action on non archived workflows", async () => {
it("should have 'Archive' action on non archived nonactive workflows", async () => {
const data = createWorkflow({
active: false,
isArchived: false,
scopes: ['workflow:delete'],
});
const { getByTestId, emitted } = renderComponent({
props: { data },
});
const cardActions = getByTestId('workflow-card-actions');
expect(cardActions).toBeInTheDocument();
const cardActionsOpener = within(cardActions).getByRole('button');
expect(cardActionsOpener).toBeInTheDocument();
const controllingId = cardActionsOpener.getAttribute('aria-controls');
await userEvent.click(cardActions);
const actions = document.querySelector(`#${controllingId}`);
if (!actions) {
throw new Error('Actions menu not found');
}
expect(actions).toHaveTextContent('Archive');
expect(actions).not.toHaveTextContent('Unarchive');
expect(actions).not.toHaveTextContent('Delete');
await userEvent.click(getByTestId('action-archive'));
expect(message.confirm).not.toHaveBeenCalled();
expect(workflowsStore.archiveWorkflow).toHaveBeenCalledTimes(1);
expect(workflowsStore.archiveWorkflow).toHaveBeenCalledWith(data.id);
expect(toast.showError).not.toHaveBeenCalled();
expect(toast.showMessage).toHaveBeenCalledTimes(1);
expect(emitted()['workflow:archived']).toHaveLength(1);
});
it("should confirm 'Archive' action on active workflows", async () => {
const data = createWorkflow({
isArchived: false,
active: true,
scopes: ['workflow:delete'],
});
@@ -232,7 +269,7 @@ describe('WorkflowCard', () => {
expect(message.confirm).toHaveBeenCalledTimes(1);
expect(workflowsStore.archiveWorkflow).toHaveBeenCalledTimes(1);
expect(workflowsStore.archiveWorkflow).toHaveBeenCalledWith(data.id);
expect(toast.showError).toHaveBeenCalledTimes(0);
expect(toast.showError).not.toHaveBeenCalled();
expect(toast.showMessage).toHaveBeenCalledTimes(1);
expect(emitted()['workflow:archived']).toHaveLength(1);
});
@@ -266,7 +303,7 @@ describe('WorkflowCard', () => {
expect(workflowsStore.unarchiveWorkflow).toHaveBeenCalledTimes(1);
expect(workflowsStore.unarchiveWorkflow).toHaveBeenCalledWith(data.id);
expect(toast.showError).toHaveBeenCalledTimes(0);
expect(toast.showError).not.toHaveBeenCalled();
expect(toast.showMessage).toHaveBeenCalledTimes(1);
expect(emitted()['workflow:unarchived']).toHaveLength(1);
});
@@ -301,7 +338,7 @@ describe('WorkflowCard', () => {
expect(message.confirm).toHaveBeenCalledTimes(1);
expect(workflowsStore.deleteWorkflow).toHaveBeenCalledTimes(1);
expect(workflowsStore.deleteWorkflow).toHaveBeenCalledWith(data.id);
expect(toast.showError).toHaveBeenCalledTimes(0);
expect(toast.showError).not.toHaveBeenCalled();
expect(toast.showMessage).toHaveBeenCalledTimes(1);
expect(emitted()['workflow:deleted']).toHaveLength(1);
});

View File

@@ -307,24 +307,26 @@ async function deleteWorkflow() {
}
async function archiveWorkflow() {
const archiveConfirmed = await message.confirm(
locale.baseText('mainSidebar.confirmMessage.workflowArchive.message', {
interpolate: { workflowName: props.data.name },
}),
locale.baseText('mainSidebar.confirmMessage.workflowArchive.headline'),
{
type: 'warning',
confirmButtonText: locale.baseText(
'mainSidebar.confirmMessage.workflowArchive.confirmButtonText',
),
cancelButtonText: locale.baseText(
'mainSidebar.confirmMessage.workflowArchive.cancelButtonText',
),
},
);
if (props.data.active) {
const archiveConfirmed = await message.confirm(
locale.baseText('mainSidebar.confirmMessage.workflowArchive.message', {
interpolate: { workflowName: props.data.name },
}),
locale.baseText('mainSidebar.confirmMessage.workflowArchive.headline'),
{
type: 'warning',
confirmButtonText: locale.baseText(
'mainSidebar.confirmMessage.workflowArchive.confirmButtonText',
),
cancelButtonText: locale.baseText(
'mainSidebar.confirmMessage.workflowArchive.cancelButtonText',
),
},
);
if (archiveConfirmed !== MODAL_CONFIRM) {
return;
if (archiveConfirmed !== MODAL_CONFIRM) {
return;
}
}
try {

View File

@@ -1025,7 +1025,7 @@
"mainSidebar.confirmMessage.workflowDelete.cancelButtonText": "",
"mainSidebar.confirmMessage.workflowDelete.confirmButtonText": "Yes, delete",
"mainSidebar.confirmMessage.workflowDelete.headline": "Delete Workflow?",
"mainSidebar.confirmMessage.workflowDelete.message": "Are you sure that you want to delete '{workflowName}'?",
"mainSidebar.confirmMessage.workflowDelete.message": "Are you sure that you want to delete '{workflowName}' permanently?",
"mainSidebar.credentials": "Credentials",
"mainSidebar.variables": "Variables",
"mainSidebar.help": "Help",