TSK-1448: Expand workbasket path with selected tab (#1333)
This commit is contained in:
parent
ea38c7ddba
commit
b8156d75ab
|
@ -51,9 +51,6 @@ export class WorkbasketAccessItemsComponent implements OnInit, OnChanges, OnDest
|
|||
@Input()
|
||||
action: ACTION;
|
||||
|
||||
@Input()
|
||||
active: string;
|
||||
|
||||
@ViewChildren('htmlInputElement')
|
||||
inputs: QueryList<ElementRef>;
|
||||
|
||||
|
@ -142,14 +139,6 @@ export class WorkbasketAccessItemsComponent implements OnInit, OnChanges, OnDest
|
|||
}
|
||||
|
||||
ngOnChanges(changes?: SimpleChanges) {
|
||||
if (!this.initialized && changes.active && changes.active.currentValue === 'accessItems') {
|
||||
this.init();
|
||||
}
|
||||
if (this.initialized && typeof changes.workbasket !== 'undefined') {
|
||||
if (changes.workbasket.currentValue.workbasketId !== changes.workbasket.previousValue.workbasketId) {
|
||||
this.init();
|
||||
}
|
||||
}
|
||||
if (changes.action) {
|
||||
this.setBadge();
|
||||
}
|
||||
|
|
|
@ -37,15 +37,15 @@
|
|||
</button>
|
||||
</mat-menu>
|
||||
</mat-toolbar>
|
||||
<mat-tab-group animationDuration="0ms" (selectedIndexChange)="selectComponent($event)">
|
||||
<mat-tab-group animationDuration="0ms" (selectedIndexChange)="selectComponent($event)" [selectedIndex]="selectedTab$ | async">
|
||||
<mat-tab label="Information">
|
||||
<taskana-administration-workbasket-information [workbasket]="workbasket" [action]="action"></taskana-administration-workbasket-information>
|
||||
</mat-tab>
|
||||
<mat-tab label="Access">
|
||||
<taskana-administration-workbasket-access-items [workbasket]="workbasket" [action]="action" [active]="tabSelected"></taskana-administration-workbasket-access-items>
|
||||
<taskana-administration-workbasket-access-items [workbasket]="workbasket" [action]="action"></taskana-administration-workbasket-access-items>
|
||||
</mat-tab>
|
||||
<mat-tab label="Distribution Targets">
|
||||
<taskana-administration-workbasket-distribution-targets [workbasket]="workbasket" [action]="action" [active]="tabSelected"></taskana-administration-workbasket-distribution-targets>
|
||||
<taskana-administration-workbasket-distribution-targets [workbasket]="workbasket" [action]="action"></taskana-administration-workbasket-distribution-targets>
|
||||
</mat-tab>
|
||||
</mat-tab-group>
|
||||
<mat-progress-bar mode="query" *ngIf="requestInProgress"></mat-progress-bar>
|
||||
|
|
|
@ -15,11 +15,7 @@ import { RequestInProgressService } from '../../../shared/services/request-in-pr
|
|||
import { SelectedRouteService } from '../../../shared/services/selected-route/selected-route';
|
||||
import { MatSnackBarModule } from '@angular/material/snack-bar';
|
||||
import { MatDialogModule } from '@angular/material/dialog';
|
||||
import {
|
||||
engineConfigurationMock,
|
||||
selectedWorkbasketMock,
|
||||
workbasketReadStateMock
|
||||
} from '../../../shared/store/mock-data/mock-store';
|
||||
import { selectedWorkbasketMock, workbasketReadStateMock } from '../../../shared/store/mock-data/mock-store';
|
||||
import { StartupService } from '../../../shared/services/startup/startup.service';
|
||||
import { TaskanaEngineService } from '../../../shared/services/taskana-engine/taskana-engine.service';
|
||||
import { WindowRefService } from '../../../shared/services/window/window.service';
|
||||
|
@ -29,6 +25,8 @@ import { MatTabsModule } from '@angular/material/tabs';
|
|||
import { MatMenuModule } from '@angular/material/menu';
|
||||
import { MatToolbarModule } from '@angular/material/toolbar';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { CreateWorkbasket } from '../../../shared/store/workbasket-store/workbasket.actions';
|
||||
import { take } from 'rxjs/operators';
|
||||
|
||||
@Component({ selector: 'taskana-shared-spinner', template: '' })
|
||||
class SpinnerStub {
|
||||
|
@ -140,7 +138,6 @@ describe('WorkbasketDetailsComponent', () => {
|
|||
workbasket: workbasketCreateState
|
||||
});
|
||||
fixture.detectChanges();
|
||||
expect(component.tabSelected).toMatch('information');
|
||||
expect(component.selectedId).toBeUndefined();
|
||||
});
|
||||
|
||||
|
@ -165,9 +162,13 @@ describe('WorkbasketDetailsComponent', () => {
|
|||
expect(component.workbasket).toEqual(selectedWorkbasketMock);
|
||||
});
|
||||
|
||||
it('should select information tab when action is CREATE', () => {
|
||||
component.action = ACTION.CREATE;
|
||||
component.selectTab('workbasket');
|
||||
expect(component.tabSelected).toEqual('information');
|
||||
it('should select information tab when action is CREATE', (done) => {
|
||||
component.selectComponent(1);
|
||||
store.dispatch(new CreateWorkbasket());
|
||||
fixture.detectChanges();
|
||||
component.selectedTab$.pipe(take(1)).subscribe((tab) => {
|
||||
expect(tab).toEqual(0);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -9,6 +9,7 @@ import { Select, Store } from '@ngxs/store';
|
|||
import { takeUntil } from 'rxjs/operators';
|
||||
import { WorkbasketAndAction, WorkbasketSelectors } from '../../../shared/store/workbasket-store/workbasket.selectors';
|
||||
import { TaskanaDate } from '../../../shared/util/taskana.date';
|
||||
import { Location } from '@angular/common';
|
||||
import { ICONTYPES } from '../../../shared/models/icon-types';
|
||||
import {
|
||||
DeselectWorkbasket,
|
||||
|
@ -16,6 +17,7 @@ import {
|
|||
SelectComponent
|
||||
} from '../../../shared/store/workbasket-store/workbasket.actions';
|
||||
import { ButtonAction } from '../../models/button-action';
|
||||
import { WorkbasketComponent } from '../../models/workbasket-component';
|
||||
|
||||
@Component({
|
||||
selector: 'taskana-administration-workbasket-details',
|
||||
|
@ -28,12 +30,14 @@ export class WorkbasketDetailsComponent implements OnInit, OnDestroy, OnChanges
|
|||
selectedId: string;
|
||||
requestInProgress = false;
|
||||
action: ACTION;
|
||||
tabSelected = 'information';
|
||||
badgeMessage = '';
|
||||
|
||||
@Select(WorkbasketSelectors.selectedWorkbasket)
|
||||
selectedWorkbasket$: Observable<Workbasket>;
|
||||
|
||||
@Select(WorkbasketSelectors.selectedComponent)
|
||||
selectedTab$: Observable<number>;
|
||||
|
||||
@Select(WorkbasketSelectors.workbasketActiveAction)
|
||||
activeAction$: Observable<ACTION>;
|
||||
|
||||
|
@ -43,6 +47,7 @@ export class WorkbasketDetailsComponent implements OnInit, OnDestroy, OnChanges
|
|||
destroy$ = new Subject<void>();
|
||||
|
||||
constructor(
|
||||
private location: Location,
|
||||
private route: ActivatedRoute,
|
||||
private router: Router,
|
||||
private domainService: DomainService,
|
||||
|
@ -54,7 +59,6 @@ export class WorkbasketDetailsComponent implements OnInit, OnDestroy, OnChanges
|
|||
this.selectedWorkbasketAndAction$.pipe(takeUntil(this.destroy$)).subscribe((selectedWorkbasketAndAction) => {
|
||||
this.action = selectedWorkbasketAndAction.action;
|
||||
if (this.action === ACTION.CREATE) {
|
||||
this.tabSelected = 'information';
|
||||
this.selectedId = undefined;
|
||||
this.badgeMessage = 'Creating new workbasket';
|
||||
this.initWorkbasket();
|
||||
|
@ -99,10 +103,6 @@ export class WorkbasketDetailsComponent implements OnInit, OnDestroy, OnChanges
|
|||
this.router.navigate(['./'], { relativeTo: this.route.parent });
|
||||
}
|
||||
|
||||
selectTab(tab) {
|
||||
this.tabSelected = this.action === ACTION.CREATE ? 'information' : tab;
|
||||
}
|
||||
|
||||
getWorkbasketInformation(selectedWorkbasket?: Workbasket) {
|
||||
let workbasketIdSelected: string;
|
||||
if (selectedWorkbasket) {
|
||||
|
@ -145,19 +145,6 @@ export class WorkbasketDetailsComponent implements OnInit, OnDestroy, OnChanges
|
|||
|
||||
selectComponent(index) {
|
||||
this.store.dispatch(new SelectComponent(index));
|
||||
switch (index) {
|
||||
case 0:
|
||||
this.selectTab('information');
|
||||
break;
|
||||
case 1:
|
||||
this.selectTab('access-items');
|
||||
break;
|
||||
case 2:
|
||||
this.selectTab('distribution-targets');
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
onSubmit() {
|
||||
|
|
|
@ -42,9 +42,6 @@ export class WorkbasketDistributionTargetsComponent implements OnInit, OnChanges
|
|||
@Input()
|
||||
action: ACTION;
|
||||
|
||||
@Input()
|
||||
active: string;
|
||||
|
||||
badgeMessage = '';
|
||||
|
||||
distributionTargetsSelectedResource: WorkbasketDistributionTargets;
|
||||
|
@ -95,9 +92,6 @@ export class WorkbasketDistributionTargetsComponent implements OnInit, OnChanges
|
|||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
if (!this.initialized && changes.active && changes.active.currentValue === 'distributionTargets') {
|
||||
this.init();
|
||||
}
|
||||
if (changes.action) {
|
||||
this.setBadge();
|
||||
}
|
||||
|
|
|
@ -74,7 +74,6 @@ export class WorkbasketInformationComponent implements OnInit, OnChanges, OnDest
|
|||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.store.dispatch(new SelectComponent(WorkbasketComponent.INFORMATION));
|
||||
this.allTypes = new Map([
|
||||
['PERSONAL', 'Personal'],
|
||||
['GROUP', 'Group'],
|
||||
|
|
|
@ -16,6 +16,7 @@ import { TaskanaType } from '../../../shared/models/taskana-type';
|
|||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatSnackBarModule } from '@angular/material/snack-bar';
|
||||
import { MatDialogModule } from '@angular/material/dialog';
|
||||
import { RouterTestingModule } from '@angular/router/testing';
|
||||
|
||||
const getDomainFn = jest.fn().mockReturnValue(true);
|
||||
const domainServiceMock = jest.fn().mockImplementation(
|
||||
|
@ -53,6 +54,7 @@ describe('WorkbasketListToolbarComponent', () => {
|
|||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
HttpClientTestingModule,
|
||||
RouterTestingModule,
|
||||
NgxsModule.forRoot([WorkbasketState]),
|
||||
BrowserAnimationsModule,
|
||||
MatIconModule,
|
||||
|
|
|
@ -22,6 +22,7 @@ import { MatSelectModule } from '@angular/material/select';
|
|||
import { FormsModule } from '@angular/forms';
|
||||
import { MatListModule, MatSelectionList } from '@angular/material/list';
|
||||
import { DomainService } from '../../../shared/services/domain/domain.service';
|
||||
import { RouterTestingModule } from '@angular/router/testing';
|
||||
|
||||
const workbasketSavedTriggeredFn = jest.fn().mockReturnValue(of(1));
|
||||
const workbasketSummaryFn = jest.fn().mockReturnValue(of({}));
|
||||
|
@ -99,6 +100,7 @@ describe('WorkbasketListComponent', () => {
|
|||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
NgxsModule.forRoot([WorkbasketState]),
|
||||
RouterTestingModule,
|
||||
MatSnackBarModule,
|
||||
MatDialogModule,
|
||||
FormsModule,
|
||||
|
|
|
@ -31,6 +31,7 @@ import { WorkbasketDistributionTargets } from '../../models/workbasket-distribut
|
|||
import { WorkbasketSummary } from '../../models/workbasket-summary';
|
||||
import { WorkbasketComponent } from '../../../administration/models/workbasket-component';
|
||||
import { ButtonAction } from '../../../administration/models/button-action';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
|
||||
class InitializeStore {
|
||||
static readonly type = '[Workbasket] Initializing state';
|
||||
|
@ -41,9 +42,36 @@ export class WorkbasketState implements NgxsAfterBootstrap {
|
|||
constructor(
|
||||
private workbasketService: WorkbasketService,
|
||||
private location: Location,
|
||||
private notificationService: NotificationService
|
||||
private notificationService: NotificationService,
|
||||
private route: ActivatedRoute
|
||||
) {}
|
||||
|
||||
@Action(InitializeStore)
|
||||
initializeStore(ctx: StateContext<WorkbasketStateModel>): Observable<any> {
|
||||
// read the selected tab from the route
|
||||
this.route.queryParams.pipe(take(2)).subscribe((params) => {
|
||||
let tabName: string = params.tab;
|
||||
let tab: number;
|
||||
|
||||
switch (tabName) {
|
||||
case 'information':
|
||||
tab = WorkbasketComponent.INFORMATION;
|
||||
break;
|
||||
case 'access-items':
|
||||
tab = WorkbasketComponent.ACCESS_ITEMS;
|
||||
break;
|
||||
case 'distribution-targets':
|
||||
tab = WorkbasketComponent.DISTRIBUTION_TARGETS;
|
||||
break;
|
||||
default:
|
||||
tab = WorkbasketComponent.INFORMATION;
|
||||
}
|
||||
|
||||
ctx.dispatch(new SelectComponent(tab));
|
||||
});
|
||||
return of();
|
||||
}
|
||||
|
||||
@Action(GetWorkbasketsSummary)
|
||||
getWorkbasketsSummary(ctx: StateContext<WorkbasketStateModel>, action: GetWorkbasketsSummary): Observable<any> {
|
||||
ctx.patchState({
|
||||
|
@ -75,7 +103,25 @@ export class WorkbasketState implements NgxsAfterBootstrap {
|
|||
|
||||
@Action(SelectWorkbasket)
|
||||
selectWorkbasket(ctx: StateContext<WorkbasketStateModel>, action: SelectWorkbasket): Observable<any> {
|
||||
this.location.go(this.location.path().replace(/(workbaskets).*/g, `workbaskets/(detail:${action.workbasketId})`));
|
||||
let selectedComponent;
|
||||
switch (ctx.getState().selectedComponent) {
|
||||
case WorkbasketComponent.INFORMATION:
|
||||
selectedComponent = 'information';
|
||||
break;
|
||||
case WorkbasketComponent.ACCESS_ITEMS:
|
||||
selectedComponent = 'access-items';
|
||||
break;
|
||||
case WorkbasketComponent.DISTRIBUTION_TARGETS:
|
||||
selectedComponent = 'distribution-targets';
|
||||
break;
|
||||
}
|
||||
|
||||
this.location.go(
|
||||
this.location
|
||||
.path()
|
||||
.replace(/(workbaskets).*/g, `workbaskets/(detail:${action.workbasketId})?tab=${selectedComponent}`)
|
||||
);
|
||||
|
||||
const id = action.workbasketId;
|
||||
if (typeof id !== 'undefined') {
|
||||
return this.workbasketService.getWorkBasket(id).pipe(
|
||||
|
@ -106,6 +152,7 @@ export class WorkbasketState implements NgxsAfterBootstrap {
|
|||
this.location.go(this.location.path().replace(/(workbaskets).*/g, 'workbaskets/(detail:new-workbasket)'));
|
||||
ctx.patchState({
|
||||
selectedWorkbasket: undefined,
|
||||
selectedComponent: WorkbasketComponent.INFORMATION,
|
||||
action: ACTION.CREATE
|
||||
});
|
||||
return of(null);
|
||||
|
@ -122,12 +169,15 @@ export class WorkbasketState implements NgxsAfterBootstrap {
|
|||
switch (action.component) {
|
||||
case WorkbasketComponent.INFORMATION:
|
||||
ctx.patchState({ selectedComponent: WorkbasketComponent.INFORMATION });
|
||||
this.location.go(this.location.path().replace(/(tab).*/g, 'tab=information'));
|
||||
break;
|
||||
case WorkbasketComponent.ACCESS_ITEMS:
|
||||
ctx.patchState({ selectedComponent: WorkbasketComponent.ACCESS_ITEMS });
|
||||
this.location.go(this.location.path().replace(/(tab).*/g, 'tab=access-items'));
|
||||
break;
|
||||
case WorkbasketComponent.DISTRIBUTION_TARGETS:
|
||||
ctx.patchState({ selectedComponent: WorkbasketComponent.DISTRIBUTION_TARGETS });
|
||||
this.location.go(this.location.path().replace(/(tab).*/g, 'tab=distribution-targets'));
|
||||
break;
|
||||
}
|
||||
return of(null);
|
||||
|
|
Loading…
Reference in New Issue