diff --git a/frontend/app/components/wp-panels/keep-tab/keep-tab.service.test.ts b/frontend/app/components/wp-panels/keep-tab/keep-tab.service.test.ts index 4dbcc76f33..9730ad3340 100644 --- a/frontend/app/components/wp-panels/keep-tab/keep-tab.service.test.ts +++ b/frontend/app/components/wp-panels/keep-tab/keep-tab.service.test.ts @@ -75,6 +75,18 @@ describe('keepTab service', () => { it('should keep the previous value of currentDetailsTab', () => { expect(keepTab.currentDetailsTab).to.eq(defaults.detailsTab); }); + + it('should propagate the previous change', () => { + var cb = sinon.spy(); + + var expected = { + show: 'new-show-route', + details: keepTab.currentDetailsTab + } + + keepTab.observable.subscribe(cb); + expect(cb).to.have.been.calledWith(expected); + }); }); describe('when opening a details route', () => { @@ -94,5 +106,22 @@ describe('keepTab service', () => { it('should keep the previous value of currentDetailsTab', () => { expect(keepTab.currentShowTab).to.eq(defaults.showTab); }); + + it('should propagate the previous and next change', () => { + var cb = sinon.spy(); + + var expected = { + details: 'new-details-route', + show: keepTab.currentShowTab + } + + keepTab.observable.subscribe(cb); + expect(cb).to.have.been.calledWith(expected); + + $rootScope.$emit('$stateChangeSuccess'); + + expect(cb).to.have.been.calledTwice; + }); + }); }); diff --git a/frontend/app/components/wp-panels/keep-tab/keep-tab.service.ts b/frontend/app/components/wp-panels/keep-tab/keep-tab.service.ts index 09bde2ac5f..2d0e69376f 100644 --- a/frontend/app/components/wp-panels/keep-tab/keep-tab.service.ts +++ b/frontend/app/components/wp-panels/keep-tab/keep-tab.service.ts @@ -30,16 +30,21 @@ export class KeepTabService { protected showTab:string = 'work-packages.show.activity'; protected detailsTab:string = 'work-packages.list.details.overview'; - constructor(public $state:ng.ui.IStateService, $rootScope:ng.IRootScopeService) { + protected subject = new Rx.ReplaySubject<{ [tab: string]: string; }>(1); + + constructor(public $state:ng.ui.IStateService, protected $rootScope:ng.IRootScopeService) { 'ngInject'; this.updateTabs(); - $rootScope.$on('$stateChangeSuccess', () => { this.updateTabs(); }); } + public get observable() { + return this.subject; + } + public get currentShowTab():string { return this.showTab; } @@ -48,6 +53,13 @@ export class KeepTabService { return this.detailsTab; } + public get currentTabs():{ [tab: string]: string; } { + return { + show: this.showTab, + details: this.detailsTab + } + } + protected updateTab(stateName:string, tabName:string) { this[tabName] = this.$state.includes(stateName) ? this.$state.current.name : this[tabName]; } @@ -55,6 +67,8 @@ export class KeepTabService { protected updateTabs() { this.updateTab('work-packages.show.*', 'showTab'); this.updateTab('work-packages.list.details.*', 'detailsTab'); + + this.subject.onNext(this.currentTabs); } } diff --git a/frontend/app/components/wp-table/wp-table.directive.html b/frontend/app/components/wp-table/wp-table.directive.html index 46d00c5bdf..2fd81bee95 100644 --- a/frontend/app/components/wp-table/wp-table.directive.html +++ b/frontend/app/components/wp-table/wp-table.directive.html @@ -131,7 +131,8 @@ + ui-state="desiredSplitViewState" + ui-state-params="{workPackageId: row.object.id}"> diff --git a/frontend/app/components/wp-table/wp-table.directive.ts b/frontend/app/components/wp-table/wp-table.directive.ts index 33458c118d..45957217f0 100644 --- a/frontend/app/components/wp-table/wp-table.directive.ts +++ b/frontend/app/components/wp-table/wp-table.directive.ts @@ -26,6 +26,8 @@ // See doc/COPYRIGHT.rdoc for more details. // ++ +import {scopedObservable} from "../../helpers/angular-rx-utils"; +import {KeepTabService} from "../wp-panels/keep-tab/keep-tab.service"; angular .module('openproject.workPackages.directives') .directive('wpTable', wpTable); @@ -33,6 +35,7 @@ angular function wpTable( WorkPackagesTableService, WorkPackageService, + keepTab:KeepTabService, QueryService, $window, $rootScope, @@ -109,6 +112,16 @@ function wpTable( } }); + if ($state.includes('work-packages.list.details')) { + scope.desiredSplitViewState = $state.$current.name; + } else { + scope.desiredSplitViewState = 'work-packages.list.details.overview'; + } + + scopedObservable(scope, keepTab.observable).subscribe((tabs:any) => { + scope.desiredSplitViewState = tabs.details; + }); + function applyGrouping() { if (scope.groupByColumn != scope.workPackagesTableData.groupByColumn) { scope.groupByColumn = scope.workPackagesTableData.groupByColumn; @@ -210,7 +223,10 @@ function wpTable( setRowSelectionState(row, multipleChecked ? true : !currentRowCheckState); } - openWhenInSplitView(row.object); + // Avoid bubbling of elements within the details link + if ($event.target.parentElement.className.indexOf('wp-table--details-link') === -1) { + openWhenInSplitView(row.object); + } } }; diff --git a/frontend/bower.json b/frontend/bower.json index 378e77bba9..11a1994ed9 100644 --- a/frontend/bower.json +++ b/frontend/bower.json @@ -10,7 +10,7 @@ "angular": "~1.3.14", "angular-animate": "~1.3.14", "angular-aria": "~1.3.14", - "angular-ui-router": "0.2.15", + "angular-ui-router": "0.2.18", "angular-i18n": "~1.3.0", "angular-modal": "finnlabs/angular-modal#d45eb9ceb720b8785613ba89ba0f14f8ab197569", "angular-sanitize": "~1.3.14",