diff --git a/javascript/apps/taiga/src/app/modules/project/data-access/+state/effects/project.effects.spec.ts b/javascript/apps/taiga/src/app/modules/project/data-access/+state/effects/project.effects.spec.ts index a35f7f473..2dbddae91 100644 --- a/javascript/apps/taiga/src/app/modules/project/data-access/+state/effects/project.effects.spec.ts +++ b/javascript/apps/taiga/src/app/modules/project/data-access/+state/effects/project.effects.spec.ts @@ -36,6 +36,7 @@ import { leaveProjectSuccess, updateWorkflow, projectApiActions, + deleteWorkflow, } from '../actions/project.actions'; import { selectCurrentProject } from '../selectors/project.selectors'; import { ProjectEffects } from './project.effects'; @@ -381,4 +382,55 @@ describe('ProjectEffects', () => { expect(effects.loadWorkflows$).toBeObservable(expected); }); }); + + it('deleteWorkflow$', () => { + const workflow = WorkflowMockFactory(); + const workflow2 = WorkflowMockFactory(); + const project = ProjectMockFactory(); + + project.workflows = [workflow, workflow2]; + + const workflowRenameResult = { + ...workflow2, + slug: 'new-slug', + }; + + const projectApiService = spectator.inject(ProjectApiService); + const effects = spectator.inject(ProjectEffects); + const router = spectator.inject(Router); + + const workflowRename$ = cold('-c', { c: workflowRenameResult }); + const deleteWorkflow$ = cold('-d', { d: null }); + + store.overrideSelector(selectCurrentProject, project); + projectApiService.updateWorkflow.mockReturnValue(workflowRename$); + projectApiService.deleteWorkflow.mockReturnValue(deleteWorkflow$); + + const action = deleteWorkflow({ workflow }); + + actions$ = hot('-a', { a: action }); + + expect(effects.deleteWorkflow$).toSatisfyOnFlush(() => { + expect(projectApiService.updateWorkflow).toHaveBeenCalledWith( + 'Main', + workflow2.slug, + project.id + ); + + expect(projectApiService.deleteWorkflow).toHaveBeenCalledWith( + project.id, + workflow.slug, + undefined + ); + const expected = cold('--a', { + a: projectApiActions.deleteWorkflowSuccess({ workflow }), + }); + + expect(effects.deleteWorkflow$).toBeObservable(expected); + + expect(router.navigate).toHaveBeenCalledWith([ + `project/${project.id}/${project.slug}/kanban/${workflowRenameResult.slug}`, + ]); + }); + }); }); diff --git a/javascript/apps/taiga/src/app/modules/project/data-access/+state/effects/project.effects.ts b/javascript/apps/taiga/src/app/modules/project/data-access/+state/effects/project.effects.ts index cd4a8aacb..4932e33fc 100644 --- a/javascript/apps/taiga/src/app/modules/project/data-access/+state/effects/project.effects.ts +++ b/javascript/apps/taiga/src/app/modules/project/data-access/+state/effects/project.effects.ts @@ -15,7 +15,7 @@ import { fetch, pessimisticUpdate } from '@ngrx/router-store/data-persistence'; import { Store } from '@ngrx/store'; import { TuiNotification } from '@taiga-ui/core'; import { ProjectApiService } from '@taiga/api'; -import { EMPTY, of } from 'rxjs'; +import { EMPTY, combineLatest, of } from 'rxjs'; import { catchError, exhaustMap, @@ -274,34 +274,57 @@ export class ProjectEffects { ]), pessimisticUpdate({ run: (action, project) => { - return this.projectApiService - .deleteWorkflow(project.id, action.workflow.slug, action.moveTo) - .pipe( - map(() => { - this.movedWorkflow.statuses = action.workflow.statuses; + const afterDeleteWorkflows = project.workflows.filter( + (w) => w.slug !== action.workflow.slug + ); - setTimeout(() => { - this.movedWorkflow.statuses = null; - }, 500); + let workflowRename$ = of(project.workflows[0].slug); + + if ( + afterDeleteWorkflows.length === 1 && + afterDeleteWorkflows[0].name !== 'Main' + ) { + workflowRename$ = this.projectApiService + .updateWorkflow('Main', afterDeleteWorkflows[0].slug, project.id) + .pipe( + map((result) => { + return result.slug; + }) + ); + } - void this.router.navigate([ - `project/${project.id}/${project.slug}/kanban/${ - action.moveTo ? action.moveTo : project.workflows[0].slug - }`, - ]); + const deleteWorkflow$ = this.projectApiService.deleteWorkflow( + project.id, + action.workflow.slug, + action.moveTo + ); - this.appService.toastNotification({ - message: 'errors.deleted_workflow', - paramsMessage: { name: action.workflow.name }, - status: TuiNotification.Info, - autoClose: true, - }); + return combineLatest([workflowRename$, deleteWorkflow$]).pipe( + map(([workflowSlug]) => { + this.movedWorkflow.statuses = action.workflow.statuses; - return ProjectActions.projectApiActions.deleteWorkflowSuccess({ - workflow: action.workflow, - }); - }) - ); + setTimeout(() => { + this.movedWorkflow.statuses = null; + }, 500); + + void this.router.navigate([ + `project/${project.id}/${project.slug}/kanban/${ + action.moveTo ? action.moveTo : workflowSlug + }`, + ]); + + this.appService.toastNotification({ + message: 'errors.deleted_workflow', + paramsMessage: { name: action.workflow.name }, + status: TuiNotification.Info, + autoClose: true, + }); + + return ProjectActions.projectApiActions.deleteWorkflowSuccess({ + workflow: action.workflow, + }); + }) + ); }, onError: (_, httpResponse: HttpErrorResponse) => { return this.appService.errorManagement(httpResponse);