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({