diff --git a/javascript/apps/taiga/src/app/modules/project/feature-kanban/data-access/+state/reducers/kanban.reducer.ts b/javascript/apps/taiga/src/app/modules/project/feature-kanban/data-access/+state/reducers/kanban.reducer.ts index ba345d08b..fdeb1a3c9 100644 --- a/javascript/apps/taiga/src/app/modules/project/feature-kanban/data-access/+state/reducers/kanban.reducer.ts +++ b/javascript/apps/taiga/src/app/modules/project/feature-kanban/data-access/+state/reducers/kanban.reducer.ts @@ -107,11 +107,15 @@ export const initialKanbanState: KanbanState = { export const reducer = createImmerReducer( initialKanbanState, - on(KanbanActions.initKanban, (state): KanbanState => { - state = { ...initialKanbanState }; + on( + KanbanActions.initKanban, + KanbanActions.loadWorkflowKanban, + (state): KanbanState => { + state = { ...initialKanbanState }; - return state; - }), + return state; + } + ), on(KanbanActions.openCreateStoryForm, (state, { status }): KanbanState => { state.createStoryForm = status; @@ -837,7 +841,7 @@ export const kanbanFeature = createFeature({ selectDraggingStatus, selectStatusDropCandidate, (workflow, currentStatus, statusDropCandidate) => { - if (!workflow) { + if (!workflow || !workflow.statuses) { return []; } diff --git a/javascript/apps/taiga/src/app/modules/project/feature-kanban/project-feature-kanban.component.html b/javascript/apps/taiga/src/app/modules/project/feature-kanban/project-feature-kanban.component.html index 661635335..394acec6a 100644 --- a/javascript/apps/taiga/src/app/modules/project/feature-kanban/project-feature-kanban.component.html +++ b/javascript/apps/taiga/src/app/modules/project/feature-kanban/project-feature-kanban.component.html @@ -24,7 +24,12 @@ [workflows]="vm.workflows" [workflow]="vm.workflow">
- +
{{ t('kanban.empty') }}
diff --git a/javascript/apps/taiga/src/app/modules/project/feature-kanban/project-feature-kanban.component.ts b/javascript/apps/taiga/src/app/modules/project/feature-kanban/project-feature-kanban.component.ts index 0a3c04015..bf89725ac 100644 --- a/javascript/apps/taiga/src/app/modules/project/feature-kanban/project-feature-kanban.component.ts +++ b/javascript/apps/taiga/src/app/modules/project/feature-kanban/project-feature-kanban.component.ts @@ -41,7 +41,6 @@ import { take, } from 'rxjs'; import * as ProjectActions from '~/app/modules/project/data-access/+state/actions/project.actions'; -import { selectWorkflow as selectWorkflowStoryDetail } from '~/app/modules/project/story-detail/data-access/+state/selectors/story-detail.selectors'; import { selectCurrentProject, selectMembers, @@ -82,7 +81,6 @@ import { KanbanHeaderComponent } from './components/kanban-header/kanban-header. interface ComponentState { loadingWorkflow: KanbanState['loadingWorkflow']; workflow: KanbanState['workflow']; - workflowStoryDetail: KanbanState['workflow']; workflows: Workflow[]; invitePeopleModal: boolean; showStoryDetail: boolean; @@ -208,16 +206,8 @@ export class ProjectFeatureKanbanComponent { combineLatest([ this.state.select('storyView'), this.state.select('showStoryDetail'), - this.state.select('workflow'), - this.state.select('workflowStoryDetail'), ]), - ([storyView, showStoryDetail, workflow, workflowStoryDetail]) => { - if (showStoryDetail && !workflow && workflowStoryDetail?.slug) { - // when there is a story open we should init kanban this way - this.store.dispatch( - KanbanActions.initKanban({ workflow: workflowStoryDetail.slug }) - ); - } + ([storyView, showStoryDetail]) => { if (showStoryDetail && storyView === 'side-view') { this.setCloseShortcut(); this.shortcutsService.setScope('side-view'); @@ -228,10 +218,6 @@ export class ProjectFeatureKanbanComponent { ); this.state.connect('storyView', this.store.select(selectStoryView)); this.state.connect('workflow', this.store.select(selectWorkflow)); - this.state.connect( - 'workflowStoryDetail', - this.store.select(selectWorkflowStoryDetail) - ); this.state.connect( 'columns', this.store.select(kanbanFeature.selectColums) diff --git a/javascript/apps/taiga/src/app/modules/project/feature-shell/project-feature-shell-routing.module.ts b/javascript/apps/taiga/src/app/modules/project/feature-shell/project-feature-shell-routing.module.ts index 60250c240..56a67ee2a 100644 --- a/javascript/apps/taiga/src/app/modules/project/feature-shell/project-feature-shell-routing.module.ts +++ b/javascript/apps/taiga/src/app/modules/project/feature-shell/project-feature-shell-routing.module.ts @@ -23,13 +23,25 @@ const routes: Routes = [ children: [ { path: ':slug/kanban', - redirectTo: ':slug/kanban/main', - pathMatch: 'full', + loadChildren: () => + import( + '~/app/modules/project/feature-view-setter/project-feature-view-setter.module' + ).then((m) => m.ProjectFeatureViewSetterModule), + canDeactivate: [CanDeactivateGuard], + data: { + kanban: true, + }, }, { path: 'kanban', - redirectTo: '/kanban/main', - pathMatch: 'full', + loadChildren: () => + import( + '~/app/modules/project/feature-view-setter/project-feature-view-setter.module' + ).then((m) => m.ProjectFeatureViewSetterModule), + canDeactivate: [CanDeactivateGuard], + data: { + kanban: true, + }, }, { path: ':slug/kanban/:workflow', diff --git a/javascript/apps/taiga/src/app/modules/project/feature-view-setter/project-feature-view-setter.component.ts b/javascript/apps/taiga/src/app/modules/project/feature-view-setter/project-feature-view-setter.component.ts index 6e7eb1839..4712c1f35 100644 --- a/javascript/apps/taiga/src/app/modules/project/feature-view-setter/project-feature-view-setter.component.ts +++ b/javascript/apps/taiga/src/app/modules/project/feature-view-setter/project-feature-view-setter.component.ts @@ -24,6 +24,7 @@ import { pairwise, startWith, combineLatest, + of, } from 'rxjs'; import { RouteHistoryService } from '~/app/shared/route-history/route-history.service'; import { StoryDetailActions } from '../story-detail/data-access/+state/actions/story-detail.actions'; @@ -43,6 +44,7 @@ import { RxState } from '@rx-angular/state'; import { CommonModule } from '@angular/common'; import { StoryDetail, StoryView, Project, Story, Workflow } from '@taiga/data'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; +import { selectCurrentWorkflowSlug } from '~/app/modules/project/feature-kanban/data-access/+state/selectors/kanban.selectors'; interface ProjectFeatureViewSetterComponentState { storyView: StoryView; @@ -50,6 +52,7 @@ interface ProjectFeatureViewSetterComponentState { isKanban: boolean; kanbanHost: ViewContainerRef | undefined; url: string; + workflowSlug: Workflow['slug']; } interface StoryParams { @@ -98,6 +101,10 @@ export class ProjectFeatureViewSetterComponent implements OnDestroy { distinctUntilChanged() ) ); + this.state.connect( + 'workflowSlug', + this.store.select(selectCurrentWorkflowSlug) + ); this.state.hold( this.state.select('kanbanHost').pipe(distinctUntilChanged(), filterNil()), @@ -120,24 +127,14 @@ export class ProjectFeatureViewSetterComponent implements OnDestroy { this.state.select('url'), this.route.data, this.route.params, + this.state.select('workflowSlug'), ]) .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(([url, data, params]) => { - this.state.connect( - 'isKanban', - this.state - .select('url') - .pipe( - map((url) => - url.endsWith(`/kanban/${params.workflow as Workflow['slug']}`) - ) - ) - ); - - if ( - !url.endsWith(`/kanban/${params.workflow as Workflow['slug']}`) && - !!data.stories - ) { + .subscribe(([url, data, params, workflowSlug]) => { + const isKanbanUrl = url.endsWith(`/kanban/${workflowSlug}`); + this.state.connect('isKanban', of(isKanbanUrl)); + + if (!isKanbanUrl && !!data.stories) { const storyParams = params as StoryParams; const needRedirect = params.slug !== (data.project as Project).slug; if (needRedirect) { diff --git a/javascript/apps/taiga/src/app/modules/project/story-detail/data-access/+state/effects/story-detail.effects.ts b/javascript/apps/taiga/src/app/modules/project/story-detail/data-access/+state/effects/story-detail.effects.ts index 3262f9b31..cbf413c7a 100644 --- a/javascript/apps/taiga/src/app/modules/project/story-detail/data-access/+state/effects/story-detail.effects.ts +++ b/javascript/apps/taiga/src/app/modules/project/story-detail/data-access/+state/effects/story-detail.effects.ts @@ -65,6 +65,11 @@ export class StoryDetailEffects { project.workflows?.find( (workflow) => workflow.slug === action.story.workflow.slug ); + if (!workflow?.statuses) { + return of( + KanbanActions.initKanban({ workflow: action.story.workflow.slug }) + ); + } if (workflow?.slug === action.story.workflow.slug) { return of( StoryDetailApiActions.fetchWorkflowSuccess({