TSK-1503: Refactored copy function and saving mechanism

This commit is contained in:
Sofie Hofmann 2021-01-25 08:36:50 +01:00
parent abfa07ce6a
commit 7e965a2709
15 changed files with 265 additions and 327 deletions

View File

@ -31,7 +31,6 @@ import { WorkbasketOverviewComponent } from './components/workbasket-overview/wo
/**
* Services
*/
import { SavingWorkbasketService } from './services/saving-workbaskets.service';
import { ClassificationDefinitionService } from './services/classification-definition.service';
import { WorkbasketDefinitionService } from './services/workbasket-definition.service';
import { ImportExportService } from './services/import-export.service';
@ -113,7 +112,6 @@ const DECLARATIONS = [
providers: [
ClassificationDefinitionService,
WorkbasketDefinitionService,
SavingWorkbasketService,
ClassificationCategoriesService,
ImportExportService
],

View File

@ -6,7 +6,6 @@ import { Observable, of } from 'rxjs';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { TypeAheadComponent } from '../../../shared/components/type-ahead/type-ahead.component';
import { TypeaheadModule } from 'ngx-bootstrap';
import { SavingWorkbasketService } from '../../services/saving-workbaskets.service';
import { RequestInProgressService } from '../../../shared/services/request-in-progress/request-in-progress.service';
import { FormsValidatorService } from '../../../shared/services/forms-validator/forms-validator.service';
import { NotificationService } from '../../../shared/services/notifications/notification.service';
@ -31,8 +30,6 @@ import {
UpdateWorkbasketAccessItems
} from '../../../shared/store/workbasket-store/workbasket.actions';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { ACTION } from '../../../shared/models/action';
import { WorkbasketAccessItems } from '../../../shared/models/workbasket-access-items';
import { MatSelectModule } from '@angular/material/select';
import { MatAutocompleteModule } from '@angular/material/autocomplete';
import { MatFormFieldModule } from '@angular/material/form-field';
@ -47,12 +44,6 @@ class SpinnerStub {
@Input() positionClass: string;
}
const savingWorkbasketServiceSpy = jest.fn().mockImplementation(
(): Partial<SavingWorkbasketService> => ({
triggeredAccessItemsSaving: jest.fn().mockReturnValue(of(true))
})
);
const requestInProgressServiceSpy = jest.fn().mockImplementation(
(): Partial<RequestInProgressService> => ({
setRequestInProgress: jest.fn()
@ -106,7 +97,6 @@ describe('WorkbasketAccessItemsComponent', () => {
],
declarations: [WorkbasketAccessItemsComponent, TypeAheadComponent, SpinnerStub],
providers: [
{ provide: SavingWorkbasketService, useClass: savingWorkbasketServiceSpy },
{ provide: RequestInProgressService, useClass: requestInProgressServiceSpy },
{ provide: FormsValidatorService, useClass: formValidatorServiceSpy },
{ provide: NotificationService, useClass: notificationServiceSpy },
@ -145,14 +135,11 @@ describe('WorkbasketAccessItemsComponent', () => {
});
it('should initialize when accessItems exist', async(() => {
component.action = ACTION.COPY;
let actionDispatched = false;
component.onSave = jest.fn().mockImplementation();
actions$.pipe(ofActionDispatched(GetWorkbasketAccessItems)).subscribe(() => (actionDispatched = true));
component.init();
expect(component.initialized).toBe(true);
expect(actionDispatched).toBe(true);
expect(component.onSave).toHaveBeenCalled();
}));
it("should discard initializing when accessItems don't exist", () => {
@ -197,14 +184,4 @@ describe('WorkbasketAccessItemsComponent', () => {
expect(onSaveSpy).toHaveBeenCalled();
expect(actionDispatched).toBe(true);
});
it('should set badge correctly', () => {
component.action = ACTION.READ;
component.setBadge();
expect(component.badgeMessage).toMatch('');
component.action = ACTION.COPY;
component.setBadge();
expect(component.badgeMessage).toMatch(`Copying workbasket: ${component.workbasket.key}`);
});
});

View File

@ -16,23 +16,21 @@ import { FormArray, FormBuilder, Validators } from '@angular/forms';
import { Workbasket } from 'app/shared/models/workbasket';
import { customFieldCount, WorkbasketAccessItems } from 'app/shared/models/workbasket-access-items';
import { WorkbasketAccessItemsRepresentation } from 'app/shared/models/workbasket-access-items-representation';
import { ACTION } from 'app/shared/models/action';
import { SavingInformation, SavingWorkbasketService } from 'app/administration/services/saving-workbaskets.service';
import { RequestInProgressService } from 'app/shared/services/request-in-progress/request-in-progress.service';
import { highlight } from 'app/shared/animations/validation.animation';
import { FormsValidatorService } from 'app/shared/services/forms-validator/forms-validator.service';
import { AccessIdDefinition } from 'app/shared/models/access-id';
import { EngineConfigurationSelectors } from 'app/shared/store/engine-configuration-store/engine-configuration.selectors';
import { filter, takeUntil } from 'rxjs/operators';
import { filter, take, takeUntil } from 'rxjs/operators';
import { NOTIFICATION_TYPES } from '../../../shared/models/notifications';
import { NotificationService } from '../../../shared/services/notifications/notification.service';
import { AccessItemsCustomisation, CustomField, getCustomFields } from '../../../shared/models/customisation';
import {
GetWorkbasketAccessItems,
OnButtonPressed,
UpdateWorkbasketAccessItems,
UpdateWorkbasket
SaveNewWorkbasket,
UpdateWorkbasket,
UpdateWorkbasketAccessItems
} from '../../../shared/store/workbasket-store/workbasket.actions';
import { WorkbasketSelectors } from '../../../shared/store/workbasket-store/workbasket.selectors';
import { WorkbasketComponent } from '../../models/workbasket-component';
@ -48,16 +46,12 @@ export class WorkbasketAccessItemsComponent implements OnInit, OnChanges, OnDest
@Input()
workbasket: Workbasket;
@Input()
action: ACTION;
@Input()
expanded: boolean;
@ViewChildren('htmlInputElement')
inputs: QueryList<ElementRef>;
badgeMessage = '';
selectedRows: number[] = [];
workbasketClone: Workbasket;
@ -65,8 +59,8 @@ export class WorkbasketAccessItemsComponent implements OnInit, OnChanges, OnDest
customFields: CustomField[];
accessItemsRepresentation: WorkbasketAccessItemsRepresentation;
accessItemsClone: Array<WorkbasketAccessItems>;
accessItemsResetClone: Array<WorkbasketAccessItems>;
accessItemsClone: WorkbasketAccessItems[];
accessItemsResetClone: WorkbasketAccessItems[];
AccessItemsForm = this.formBuilder.group({
accessItemsGroups: this.formBuilder.array([])
});
@ -76,6 +70,9 @@ export class WorkbasketAccessItemsComponent implements OnInit, OnChanges, OnDest
added = false;
destroy$ = new Subject<void>();
@Select(WorkbasketSelectors.selectedWorkbasket)
selectedWorkbasket$: Observable<Workbasket>;
@Select(EngineConfigurationSelectors.accessItemsCustomisation)
accessItemsCustomization$: Observable<AccessItemsCustomisation>;
@ -89,7 +86,6 @@ export class WorkbasketAccessItemsComponent implements OnInit, OnChanges, OnDest
selectedComponent$: Observable<WorkbasketComponent>;
constructor(
private savingWorkbaskets: SavingWorkbasketService,
private requestInProgressService: RequestInProgressService,
private formBuilder: FormBuilder,
public formsValidatorService: FormsValidatorService,
@ -110,17 +106,27 @@ export class WorkbasketAccessItemsComponent implements OnInit, OnChanges, OnDest
});
this.accessItemsRepresentation$.subscribe((accessItemsRepresentation) => {
if (typeof accessItemsRepresentation !== 'undefined') {
this.accessItemsRepresentation = accessItemsRepresentation;
this.accessItemsRepresentation = { ...accessItemsRepresentation };
this.setAccessItemsGroups(accessItemsRepresentation.accessItems);
this.accessItemsClone = this.cloneAccessItems(accessItemsRepresentation.accessItems);
this.accessItemsResetClone = this.cloneAccessItems(accessItemsRepresentation.accessItems);
}
});
// saving workbasket access items when workbasket already exists
this.ngxsActions$.pipe(ofActionCompleted(UpdateWorkbasket), takeUntil(this.destroy$)).subscribe(() => {
this.onSubmit();
});
// saving workbasket access items when workbasket was copied or created
this.ngxsActions$.pipe(ofActionCompleted(SaveNewWorkbasket), takeUntil(this.destroy$)).subscribe(() => {
this.selectedWorkbasket$.pipe(take(1)).subscribe((workbasket) => {
this.accessItemsRepresentation._links = { self: { href: workbasket._links.accessItems.href } };
this.setWorkbasketIdForCopy(workbasket.workbasketId);
this.onSave();
});
});
this.buttonAction$
.pipe(takeUntil(this.destroy$))
.pipe(filter((buttonAction) => typeof buttonAction !== 'undefined'))
@ -168,9 +174,6 @@ export class WorkbasketAccessItemsComponent implements OnInit, OnChanges, OnDest
}
ngOnChanges(changes?: SimpleChanges) {
if (changes.action) {
this.setBadge();
}
if (this.workbasketClone) {
if (this.workbasketClone.workbasketId != this.workbasket.workbasketId) {
this.init();
@ -189,16 +192,6 @@ export class WorkbasketAccessItemsComponent implements OnInit, OnChanges, OnDest
this.requestInProgressService.setRequestInProgress(false);
});
this.savingWorkbaskets
.triggeredAccessItemsSaving()
.pipe(takeUntil(this.destroy$))
.subscribe((savingInformation: SavingInformation) => {
if (this.action === ACTION.COPY) {
this.accessItemsRepresentation._links.self.href = savingInformation.url;
this.setWorkbasketIdForCopy(savingInformation.workbasketId);
this.onSave();
}
});
this.initialized = true;
}
@ -291,7 +284,7 @@ export class WorkbasketAccessItemsComponent implements OnInit, OnChanges, OnDest
accessItemSelected(accessItem: AccessIdDefinition, row: number) {
this.accessItemsGroups.controls[row].get('accessId').setValue(accessItem?.accessId);
this.accessItemsGroups.controls[row].get('accessName').setValue(accessItem.name);
this.accessItemsGroups.controls[row].get('accessName').setValue(accessItem?.name);
}
onSave() {
@ -335,12 +328,6 @@ export class WorkbasketAccessItemsComponent implements OnInit, OnChanges, OnDest
}
}
setBadge() {
if (this.action === ACTION.COPY) {
this.badgeMessage = `Copying workbasket: ${this.workbasket.key}`;
}
}
cloneAccessItems(inputaccessItem): Array<WorkbasketAccessItems> {
return this.AccessItemsForm.value.accessItemsGroups.map((accessItems: WorkbasketAccessItems) => ({
...accessItems

View File

@ -2,7 +2,7 @@
<mat-toolbar class="workbasket-details__toolbar">
<h4 class="workbasket-details__title">
<span class="workbasket-details__title-name">{{workbasket.name}}</span>
<span class="workbasket-details__title-badge" *ngIf="!workbasket.workbasketId"> {{ badgeMessage }}</span>
<span class="workbasket-details__title-badge"> {{ badgeMessage$ | async }}</span>
</h4>
<span class="workbasket-details__spacer"></span>
<button mat-button class="workbasket-details__button workbasket-details__save-button"
@ -52,11 +52,11 @@
</taskana-administration-workbasket-information>
</mat-tab>
<mat-tab label="Access">
<taskana-administration-workbasket-access-items [workbasket]="workbasket" [action]="action" [expanded]="expanded">
<taskana-administration-workbasket-access-items [workbasket]="workbasket" [expanded]="expanded">
</taskana-administration-workbasket-access-items>
</mat-tab>
<mat-tab label="Distribution Targets">
<taskana-administration-workbasket-distribution-targets [workbasket]="workbasket" [action]="action">
<taskana-administration-workbasket-distribution-targets [workbasket]="workbasket">
</taskana-administration-workbasket-distribution-targets>
</mat-tab>
</mat-tab-group>

View File

@ -2,7 +2,7 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { WorkbasketDetailsComponent } from './workbasket-details.component';
import { Component, DebugElement, Input } from '@angular/core';
import { Actions, NgxsModule, Store } from '@ngxs/store';
import { Observable } from 'rxjs';
import { Observable, of } from 'rxjs';
import { Workbasket } from '../../../shared/models/workbasket';
import { ACTION } from '../../../shared/models/action';
import { WorkbasketState } from '../../../shared/store/workbasket-store/workbasket.state';
@ -25,7 +25,7 @@ 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 { CopyWorkbasket, CreateWorkbasket } from '../../../shared/store/workbasket-store/workbasket.actions';
import { take } from 'rxjs/operators';
@Component({ selector: 'taskana-administration-workbasket-information', template: '<div>i</div>' })
@ -49,6 +49,14 @@ class WorkbasketDistributionTargetsStub {
@Input() active: string;
}
const domainServiceSpy = jest.fn().mockImplementation(
(): Partial<DomainService> => ({
getSelectedDomainValue: jest.fn().mockReturnValue(of()),
getSelectedDomain: jest.fn().mockReturnValue(of('A')),
getDomains: jest.fn().mockReturnValue(of())
})
);
export const workbasketCopyState = {
selectedWorkbasket: selectedWorkbasketMock,
action: ACTION.COPY
@ -92,7 +100,7 @@ describe('WorkbasketDetailsComponent', () => {
WorkbasketInformationStub
],
providers: [
DomainService,
{ provide: DomainService, useClass: domainServiceSpy },
ImportExportService,
WorkbasketService,
RequestInProgressService,
@ -126,23 +134,32 @@ describe('WorkbasketDetailsComponent', () => {
expect(information).toBeTruthy();
});
it('should render new workbasket when action is CREATE', () => {
store.reset({
...store.snapshot(),
workbasket: workbasketCreateState
});
fixture.detectChanges();
expect(component.selectedId).toBeUndefined();
it('should render new workbasket when action is CREATE', async (done) => {
store
.dispatch(new CreateWorkbasket())
.pipe(take(1))
.subscribe(() => {
component.selectedWorkbasketAndComponentAndAction$.pipe(take(1)).subscribe((state) => {
expect(state.selectedWorkbasket.workbasketId).toBeUndefined();
done();
});
});
});
it('should render copied workbasket when action is COPY', () => {
store.reset({
...store.snapshot(),
workbasket: workbasketCopyState
});
component.ngOnInit();
fixture.detectChanges();
expect(component.workbasketCopy).toEqual(component.workbasket);
it('should render copied workbasket when action is COPY', (done) => {
const workbasket = component.workbasket;
store
.dispatch(new CopyWorkbasket(component.workbasket))
.pipe(take(1))
.subscribe(() => {
component.selectedWorkbasketAndComponentAndAction$.pipe(take(1)).subscribe((state) => {
const workbasketCopy = state.selectedWorkbasket;
expect(workbasketCopy.workbasketId).toBeUndefined();
expect(workbasketCopy.key).toEqual(workbasket.key);
expect(workbasketCopy.owner).toEqual(workbasket.owner);
done();
});
});
});
it('should render workbasket when action is READ', () => {
@ -158,11 +175,14 @@ describe('WorkbasketDetailsComponent', () => {
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();
});
store
.dispatch(new CreateWorkbasket())
.pipe(take(1))
.subscribe(() => {
component.selectedTab$.pipe(take(1)).subscribe((tab) => {
expect(tab).toEqual(0);
done();
});
});
});
});

View File

@ -1,47 +1,44 @@
import { Component, Input, OnChanges, OnDestroy, OnInit, SimpleChanges } from '@angular/core';
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { Observable, Subject } from 'rxjs';
import { Workbasket } from 'app/shared/models/workbasket';
import { ACTION } from 'app/shared/models/action';
import { DomainService } from 'app/shared/services/domain/domain.service';
import { ImportExportService } from 'app/administration/services/import-export.service';
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 { WorkbasketType } from '../../../shared/models/workbasket-type';
import {
WorkbasketAndComponentAndAction,
WorkbasketSelectors
} from '../../../shared/store/workbasket-store/workbasket.selectors';
import { Location } from '@angular/common';
import {
CopyWorkbasket,
DeselectWorkbasket,
OnButtonPressed,
SelectComponent
} from '../../../shared/store/workbasket-store/workbasket.actions';
import { ButtonAction } from '../../models/button-action';
import { RequestInProgressService } from '../../../shared/services/request-in-progress/request-in-progress.service';
import { WorkbasketComponent } from '../../models/workbasket-component';
@Component({
selector: 'taskana-administration-workbasket-details',
templateUrl: './workbasket-details.component.html',
styleUrls: ['./workbasket-details.component.scss']
})
export class WorkbasketDetailsComponent implements OnInit, OnDestroy, OnChanges {
export class WorkbasketDetailsComponent implements OnInit, OnDestroy {
workbasket: Workbasket;
workbasketCopy: Workbasket;
selectedId: string;
action: ACTION;
badgeMessage = '';
@Select(WorkbasketSelectors.selectedWorkbasket)
selectedWorkbasket$: Observable<Workbasket>;
selectedComponent: WorkbasketComponent;
@Select(WorkbasketSelectors.selectedComponent)
selectedTab$: Observable<number>;
@Select(WorkbasketSelectors.workbasketActiveAction)
activeAction$: Observable<ACTION>;
@Select(WorkbasketSelectors.badgeMessage)
badgeMessage$: Observable<string>;
@Select(WorkbasketSelectors.selectedWorkbasketAndAction)
selectedWorkbasketAndAction$: Observable<WorkbasketAndAction>;
@Select(WorkbasketSelectors.selectedWorkbasketAndComponentAndAction)
selectedWorkbasketAndComponentAndAction$: Observable<WorkbasketAndComponentAndAction>;
destroy$ = new Subject<void>();
@ -52,97 +49,38 @@ export class WorkbasketDetailsComponent implements OnInit, OnDestroy, OnChanges
private route: ActivatedRoute,
private router: Router,
private domainService: DomainService,
private importExportService: ImportExportService,
private requestInProgressService: RequestInProgressService,
private store: Store
) {}
ngOnInit() {
this.selectedWorkbasketAndAction$.pipe(takeUntil(this.destroy$)).subscribe((selectedWorkbasketAndAction) => {
this.action = selectedWorkbasketAndAction.action;
if (this.action === ACTION.CREATE) {
this.selectedId = undefined;
this.badgeMessage = 'Creating new workbasket';
this.initWorkbasket();
} else if (this.action === ACTION.COPY) {
// delete this.workbasket.key;
this.workbasketCopy = this.workbasket;
this.getWorkbasketInformation();
this.badgeMessage = `Copying workbasket: ${this.workbasket.key}`;
} else if (typeof selectedWorkbasketAndAction.selectedWorkbasket !== 'undefined') {
this.workbasket = { ...selectedWorkbasketAndAction.selectedWorkbasket };
this.getWorkbasketInformation(this.workbasket);
this.getWorkbasketFromStore();
}
getWorkbasketFromStore() {
// this is necessary since we receive workbaskets from store even when there is no update
// this would unintentionally discard changes
this.selectedWorkbasketAndComponentAndAction$.pipe(takeUntil(this.destroy$)).subscribe((object) => {
const workbasket = object.selectedWorkbasket;
const action = object.action;
const component = object.selectedComponent;
// get workbasket from store when:
// a) workbasket with another ID is selected (includes copying)
// b) empty workbasket is created
// c) saving the workbasket
const isAnotherId = this.workbasket?.workbasketId !== workbasket?.workbasketId;
const isCreation = action !== this.action && action === ACTION.CREATE;
const isSameComponent = component === this.selectedComponent;
if (isAnotherId || isCreation || isSameComponent) {
this.workbasket = { ...workbasket };
}
this.action = action;
this.selectedComponent = component;
});
this.importExportService
.getImportingFinished()
.pipe(takeUntil(this.destroy$))
.subscribe(() => {
if (this.workbasket) {
this.getWorkbasketInformation(this.workbasket);
}
});
}
ngOnChanges(changes?: SimpleChanges) {}
addDateToWorkbasket(workbasket: Workbasket) {
const date = TaskanaDate.getDate();
workbasket.created = date;
workbasket.modified = date;
}
initWorkbasket() {
const emptyWorkbasket: Workbasket = {};
emptyWorkbasket.domain = this.domainService.getSelectedDomainValue();
emptyWorkbasket.type = WorkbasketType.PERSONAL;
this.addDateToWorkbasket(emptyWorkbasket);
this.workbasket = emptyWorkbasket;
}
backClicked(): void {
this.router.navigate(['./'], { relativeTo: this.route.parent });
}
getWorkbasketInformation(selectedWorkbasket?: Workbasket) {
let workbasketIdSelected: string;
if (selectedWorkbasket) {
workbasketIdSelected = selectedWorkbasket.workbasketId;
}
this.requestInProgressService.setRequestInProgress(true);
if (!workbasketIdSelected && this.action === ACTION.CREATE) {
// CREATE
this.workbasket = {};
this.domainService
.getSelectedDomain()
.pipe(takeUntil(this.destroy$))
.subscribe((domain) => {
this.workbasket.domain = domain;
});
this.requestInProgressService.setRequestInProgress(false);
} else if (!workbasketIdSelected && this.action === ACTION.COPY) {
// COPY
this.workbasket = { ...this.workbasketCopy };
delete this.workbasket.workbasketId;
this.requestInProgressService.setRequestInProgress(false);
}
if (workbasketIdSelected) {
this.workbasket = selectedWorkbasket;
this.requestInProgressService.setRequestInProgress(false);
this.checkDomainAndRedirect();
}
}
checkDomainAndRedirect() {
this.domainService
.getSelectedDomain()
.pipe(takeUntil(this.destroy$))
.subscribe((domain) => {
if (domain !== '' && this.workbasket && this.workbasket.domain !== domain) {
this.backClicked();
}
});
}
selectComponent(index) {
@ -159,6 +97,7 @@ export class WorkbasketDetailsComponent implements OnInit, OnDestroy, OnChanges
onCopy() {
this.store.dispatch(new OnButtonPressed(ButtonAction.COPY));
this.store.dispatch(new CopyWorkbasket(this.workbasket));
}
onRemoveAsDistributionTarget() {

View File

@ -7,7 +7,6 @@ import { MatToolbarModule } from '@angular/material/toolbar';
import { MatButtonModule } from '@angular/material/button';
import { Observable, of } from 'rxjs';
import { WorkbasketService } from '../../../shared/services/workbasket/workbasket.service';
import { SavingWorkbasketService } from '../../services/saving-workbaskets.service';
import { NotificationService } from '../../../shared/services/notifications/notification.service';
import { Actions, NgxsModule, Store } from '@ngxs/store';
import { WorkbasketState } from '../../../shared/store/workbasket-store/workbasket.state';
@ -21,6 +20,7 @@ import {
} from '../../../shared/store/mock-data/mock-store';
import { WorkbasketQueryFilterParameter } from '../../../shared/models/workbasket-query-filter-parameter';
import { Pair } from '../../../shared/models/pair';
import { DomainService } from '../../../shared/services/domain/domain.service';
const routeParamsMock = { id: 'workbasket' };
const activatedRouteMock = {
@ -42,6 +42,14 @@ class WorkbasketDistributionTargetsListStub {
@Output() allSelectedChange = new EventEmitter<boolean>();
}
const domainServiceSpy = jest.fn().mockImplementation(
(): Partial<DomainService> => ({
getSelectedDomainValue: jest.fn().mockReturnValue(of()),
getSelectedDomain: jest.fn().mockReturnValue(of('A')),
getDomains: jest.fn().mockReturnValue(of())
})
);
const workbasketServiceSpy = jest.fn().mockImplementation(
(): Partial<WorkbasketService> => ({
getWorkBasketsSummary: jest.fn().mockReturnValue(of()),
@ -49,11 +57,6 @@ const workbasketServiceSpy = jest.fn().mockImplementation(
})
);
const savingWorkbasketServiceSpy = jest.fn().mockImplementation(
(): Partial<SavingWorkbasketService> => ({
triggeredDistributionTargetsSaving: jest.fn().mockReturnValue(of())
})
);
const notificationsServiceSpy = jest.fn().mockImplementation(
(): Partial<NotificationService> => ({
showToast: jest.fn().mockReturnValue(true)
@ -84,10 +87,10 @@ describe('WorkbasketDistributionTargetsComponent', () => {
declarations: [WorkbasketDistributionTargetsComponent, WorkbasketDistributionTargetsListStub],
providers: [
{ provide: WorkbasketService, useClass: workbasketServiceSpy },
{ provide: SavingWorkbasketService, useClass: savingWorkbasketServiceSpy },
{ provide: NotificationService, useClass: notificationsServiceSpy },
{ provide: ActivatedRoute, useValue: activatedRouteMock },
{ provide: RequestInProgressService, useClass: requestInProgressServiceSpy }
{ provide: RequestInProgressService, useClass: requestInProgressServiceSpy },
{ provide: DomainService, useClass: domainServiceSpy }
]
}).compileComponents();

View File

@ -5,19 +5,18 @@ import { Workbasket } from 'app/shared/models/workbasket';
import { WorkbasketSummary } from 'app/shared/models/workbasket-summary';
import { WorkbasketSummaryRepresentation } from 'app/shared/models/workbasket-summary-representation';
import { WorkbasketDistributionTargets } from 'app/shared/models/workbasket-distribution-targets';
import { ACTION } from 'app/shared/models/action';
import { WorkbasketService } from 'app/shared/services/workbasket/workbasket.service';
import { SavingWorkbasketService, SavingInformation } from 'app/administration/services/saving-workbaskets.service';
import { Page } from 'app/shared/models/page';
import { Actions, ofActionCompleted, Select, Store } from '@ngxs/store';
import { filter, takeUntil } from 'rxjs/operators';
import { filter, take, takeUntil } from 'rxjs/operators';
import { NOTIFICATION_TYPES } from '../../../shared/models/notifications';
import { NotificationService } from '../../../shared/services/notifications/notification.service';
import {
GetAvailableDistributionTargets,
GetWorkbasketDistributionTargets,
UpdateWorkbasketDistributionTargets,
UpdateWorkbasketAccessItems
SaveNewWorkbasket,
UpdateWorkbasket,
UpdateWorkbasketDistributionTargets
} from '../../../shared/store/workbasket-store/workbasket.actions';
import { WorkbasketSelectors } from '../../../shared/store/workbasket-store/workbasket.selectors';
import { ButtonAction } from '../../models/button-action';
@ -38,20 +37,17 @@ export class WorkbasketDistributionTargetsComponent implements OnInit, OnDestroy
@Input()
workbasket: Workbasket;
@Input()
action: ACTION;
toolbarState = false;
sideBySide = true;
displayingDistributionTargetsPicker = true;
distributionTargetsSelectedResource: WorkbasketDistributionTargets;
availableDistributionTargets: Array<WorkbasketSummary> = [];
distributionTargetsClone: Array<WorkbasketSummary>;
availableDistributionTargets: WorkbasketSummary[] = [];
distributionTargetsClone: WorkbasketSummary[];
distributionTargetsLeft: Array<WorkbasketSummary> = [];
distributionTargetsSelected: Array<WorkbasketSummary>;
distributionTargetsSelectedClone: Array<WorkbasketSummary>;
distributionTargetsLeft: WorkbasketSummary[] = [];
distributionTargetsSelected: WorkbasketSummary[];
distributionTargetsSelectedClone: WorkbasketSummary[];
loadingItems = false;
side = Side;
@ -81,7 +77,6 @@ export class WorkbasketDistributionTargetsComponent implements OnInit, OnDestroy
constructor(
private workbasketService: WorkbasketService,
private savingWorkbaskets: SavingWorkbasketService,
private notificationsService: NotificationService,
private store: Store,
private ngxsActions$: Actions
@ -97,7 +92,8 @@ export class WorkbasketDistributionTargetsComponent implements OnInit, OnDestroy
.subscribe((selectedWorkbasket) => {
this.workbasket = selectedWorkbasket;
});
if (Object.keys(this.workbasket).length !== 0) {
if (this.workbasket?.workbasketId) {
this.store.dispatch(new GetWorkbasketDistributionTargets(this.workbasket._links.distributionTargets.href));
this.store.dispatch(new GetAvailableDistributionTargets());
}
@ -109,16 +105,6 @@ export class WorkbasketDistributionTargetsComponent implements OnInit, OnDestroy
this.availableDistributionTargets = availableDistributionTargets.map((wb) => ({ ...wb }));
});
this.savingWorkbaskets
.triggeredDistributionTargetsSaving()
.pipe(takeUntil(this.destroy$))
.subscribe((savingInformation: SavingInformation) => {
if (this.action === ACTION.COPY) {
this.distributionTargetsSelectedResource._links.self.href = savingInformation.url;
this.onSave();
}
});
this.workbasketDistributionTargets$.subscribe((workbasketDistributionTargets) => {
if (typeof workbasketDistributionTargets !== 'undefined') {
this.distributionTargetsSelectedResource = { ...workbasketDistributionTargets };
@ -129,10 +115,21 @@ export class WorkbasketDistributionTargetsComponent implements OnInit, OnDestroy
}
});
this.ngxsActions$.pipe(ofActionCompleted(UpdateWorkbasketAccessItems), takeUntil(this.destroy$)).subscribe(() => {
// saving workbasket distributions targets when existing workbasket was modified
this.ngxsActions$.pipe(ofActionCompleted(UpdateWorkbasket), takeUntil(this.destroy$)).subscribe(() => {
this.onSave();
});
// saving workbasket distributions targets when workbasket was copied or created
this.ngxsActions$.pipe(ofActionCompleted(SaveNewWorkbasket), takeUntil(this.destroy$)).subscribe(() => {
this.selectedWorkbasket$.pipe(take(1)).subscribe((workbasket) => {
this.distributionTargetsSelectedResource._links = {
self: { href: workbasket._links.distributionTargets.href }
};
this.onSave();
});
});
this.buttonAction$
.pipe(takeUntil(this.destroy$))
.pipe(filter((buttonAction) => typeof buttonAction !== 'undefined'))
@ -261,11 +258,11 @@ export class WorkbasketDistributionTargetsComponent implements OnInit, OnDestroy
this.distributionTargetsLeft = side === Side.SELECTED ? workbaskets : this.distributionTargetsLeft;
}
getSelectedItems(originList: any): Array<any> {
getSelectedItems(originList: any): any[] {
return originList.filter((item: any) => item.selected === true);
}
unselectItems(originList: Array<any>): Array<any> {
unselectItems(originList: any[]): any[] {
return originList
.filter((item) => item.selected)
.map((item) => {
@ -283,7 +280,7 @@ export class WorkbasketDistributionTargetsComponent implements OnInit, OnDestroy
return copyList;
}
getSelectedIds(): Array<string> {
getSelectedIds(): string[] {
return this.distributionTargetsSelected.map((distributionTarget) => distributionTarget.workbasketId);
}

View File

@ -9,7 +9,6 @@ import { MapValuesPipe } from '../../../shared/pipes/map-values.pipe';
import { RemoveNoneTypePipe } from '../../../shared/pipes/remove-empty-type.pipe';
import { WorkbasketService } from '../../../shared/services/workbasket/workbasket.service';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { SavingWorkbasketService } from '../../services/saving-workbaskets.service';
import { RequestInProgressService } from '../../../shared/services/request-in-progress/request-in-progress.service';
import { FormsValidatorService } from '../../../shared/services/forms-validator/forms-validator.service';
import { NotificationService } from '../../../shared/services/notifications/notification.service';
@ -127,7 +126,6 @@ describe('WorkbasketInformationComponent', () => {
{ provide: WorkbasketService, useClass: workbasketServiceMock },
{ provide: FormsValidatorService, useClass: formValidatorServiceSpy },
{ provide: NotificationService, useClass: notificationServiceSpy },
SavingWorkbasketService,
RequestInProgressService,
DomainService,
SelectedRouteService,
@ -168,18 +166,6 @@ describe('WorkbasketInformationComponent', () => {
expect(component.workbasketClone).toMatchObject(component.workbasket);
});
it('should display create badge message when action is CREATE', () => {
component.action = ACTION.CREATE;
component.ngOnChanges();
expect(component.badgeMessage).toMatch('Creating new workbasket');
});
it('should display copy badge message when action is COPY', () => {
component.action = ACTION.COPY;
component.ngOnChanges();
expect(component.badgeMessage).toContain(`Copying workbasket: ${component.workbasket.key}`);
});
it('should submit when validatorService is true', () => {
const formsValidatorService = TestBed.inject(FormsValidatorService);
component.onSubmit();

View File

@ -5,7 +5,6 @@ import { Select, Store } from '@ngxs/store';
import { ACTION } from 'app/shared/models/action';
import { customFieldCount, Workbasket } from 'app/shared/models/workbasket';
import { TaskanaDate } from 'app/shared/util/taskana.date';
import { SavingInformation, SavingWorkbasketService } from 'app/administration/services/saving-workbaskets.service';
import { WorkbasketService } from 'app/shared/services/workbasket/workbasket.service';
import { RequestInProgressService } from 'app/shared/services/request-in-progress/request-in-progress.service';
import { FormsValidatorService } from 'app/shared/services/forms-validator/forms-validator.service';
@ -15,7 +14,6 @@ import { NOTIFICATION_TYPES } from '../../../shared/models/notifications';
import { NotificationService } from '../../../shared/services/notifications/notification.service';
import { CustomField, getCustomFields, WorkbasketsCustomisation } from '../../../shared/models/customisation';
import {
CopyWorkbasket,
MarkWorkbasketForDeletion,
RemoveDistributionTarget,
SaveNewWorkbasket,
@ -43,7 +41,6 @@ export class WorkbasketInformationComponent implements OnInit, OnChanges, OnDest
workbasketClone: Workbasket;
allTypes: Map<string, string>;
badgeMessage = '';
toggleValidationMap = new Map<string, boolean>();
lookupField = false;
@ -65,7 +62,6 @@ export class WorkbasketInformationComponent implements OnInit, OnChanges, OnDest
constructor(
private workbasketService: WorkbasketService,
private savingWorkbasket: SavingWorkbasketService,
private requestInProgressService: RequestInProgressService,
private formsValidatorService: FormsValidatorService,
private notificationService: NotificationService,
@ -109,9 +105,6 @@ export class WorkbasketInformationComponent implements OnInit, OnChanges, OnDest
case ButtonAction.UNDO:
this.onUndo();
break;
case ButtonAction.COPY:
this.copyWorkbasket();
break;
case ButtonAction.REMOVE_AS_DISTRIBUTION_TARGETS:
this.removeDistributionTargets();
break;
@ -126,11 +119,6 @@ export class WorkbasketInformationComponent implements OnInit, OnChanges, OnDest
ngOnChanges(changes?: SimpleChanges) {
this.workbasketClone = { ...this.workbasket };
if (this.action === ACTION.CREATE) {
this.badgeMessage = 'Creating new workbasket';
} else if (this.action === ACTION.COPY) {
this.badgeMessage = `Copying workbasket: ${this.workbasket.key}`;
}
}
onSubmit() {
@ -159,10 +147,6 @@ export class WorkbasketInformationComponent implements OnInit, OnChanges, OnDest
);
}
copyWorkbasket() {
this.store.dispatch(new CopyWorkbasket(this.workbasket));
}
removeDistributionTargets() {
this.store.dispatch(new RemoveDistributionTarget(this.workbasket._links.removeDistributionTargets.href));
}
@ -171,12 +155,12 @@ export class WorkbasketInformationComponent implements OnInit, OnChanges, OnDest
this.beforeRequest();
if (!this.workbasket.workbasketId) {
this.postNewWorkbasket();
return;
} else {
this.store.dispatch(new UpdateWorkbasket(this.workbasket._links.self.href, this.workbasket)).subscribe(() => {
this.requestInProgressService.setRequestInProgress(false);
this.workbasketClone = { ...this.workbasket };
});
}
this.store.dispatch(new UpdateWorkbasket(this.workbasket._links.self.href, this.workbasket)).subscribe(() => {
this.requestInProgressService.setRequestInProgress(false);
this.workbasketClone = { ...this.workbasket };
});
}
beforeRequest() {
@ -192,14 +176,6 @@ export class WorkbasketInformationComponent implements OnInit, OnChanges, OnDest
this.addDateToWorkbasket();
this.store.dispatch(new SaveNewWorkbasket(this.workbasket)).subscribe(() => {
this.afterRequest();
if (this.action === ACTION.COPY) {
this.savingWorkbasket.triggerDistributionTargetSaving(
new SavingInformation(this.workbasket._links.distributionTargets.href, this.workbasket.workbasketId)
);
this.savingWorkbasket.triggerAccessItemsSaving(
new SavingInformation(this.workbasket._links.accessItems.href, this.workbasket.workbasketId)
);
}
});
}

View File

@ -139,10 +139,15 @@ export class WorkbasketListComponent implements OnInit, OnDestroy {
}
selectWorkbasket(id: string) {
this.requestInProgressService.setRequestInProgress(true);
if (this.selectedId === id) {
this.store.dispatch(new DeselectWorkbasket());
this.store
.dispatch(new DeselectWorkbasket())
.subscribe(() => this.requestInProgressService.setRequestInProgress(false));
} else {
this.store.dispatch(new SelectWorkbasket(id));
this.store
.dispatch(new SelectWorkbasket(id))
.subscribe(() => this.requestInProgressService.setRequestInProgress(false));
}
}

View File

@ -1,7 +1,7 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { WorkbasketOverviewComponent } from './workbasket-overview.component';
import { Component, DebugElement, Input } from '@angular/core';
import { Actions, NgxsModule, ofActionDispatched, Store } from '@ngxs/store';
import { Actions, NgxsModule, ofActionCompleted, ofActionDispatched, Store } from '@ngxs/store';
import { Observable, of } from 'rxjs';
import { WorkbasketState } from '../../../shared/store/workbasket-store/workbasket.state';
import { WorkbasketService } from '../../../shared/services/workbasket/workbasket.service';
@ -18,6 +18,7 @@ import { TaskanaEngineService } from '../../../shared/services/taskana-engine/ta
import { WindowRefService } from '../../../shared/services/window/window.service';
import { workbasketReadStateMock } from '../../../shared/store/mock-data/mock-store';
import { MatIconModule } from '@angular/material/icon';
import { take } from 'rxjs/operators';
const showDialogFn = jest.fn().mockReturnValue(true);
const NotificationServiceSpy = jest.fn().mockImplementation(
@ -27,6 +28,14 @@ const NotificationServiceSpy = jest.fn().mockImplementation(
})
);
const domainServiceSpy = jest.fn().mockImplementation(
(): Partial<DomainService> => ({
getSelectedDomainValue: jest.fn().mockReturnValue(of()),
getSelectedDomain: jest.fn().mockReturnValue(of('A')),
getDomains: jest.fn().mockReturnValue(of())
})
);
const mockActivatedRoute = {
firstChild: {
params: of({
@ -79,6 +88,7 @@ describe('WorkbasketOverviewComponent', () => {
WorkbasketService,
{ provide: NotificationService, useClass: NotificationServiceSpy },
{ provide: ActivatedRoute, useValue: mockActivatedRoute },
{ provide: DomainService, useValue: domainServiceSpy },
DomainService,
RequestInProgressService,
SelectedRouteService,
@ -114,14 +124,14 @@ describe('WorkbasketOverviewComponent', () => {
expect(debugElement.nativeElement.querySelector('taskana-administration-workbasket-details')).toBeTruthy();
});
it('should display details when params id exists', async(() => {
let actionDispatched = false;
actions$.pipe(ofActionDispatched(CreateWorkbasket)).subscribe(() => (actionDispatched = true));
it('should display details when params id exists', async((done) => {
actions$.pipe(ofActionCompleted(CreateWorkbasket), take(1)).subscribe(() => {
expect(component.routerParams.id).toMatch('new-workbasket');
expect(component.showDetail).toBeTruthy();
expect(debugElement.nativeElement.querySelector('taskana-administration-workbasket-details')).toBeTruthy();
done();
});
component.ngOnInit();
expect(actionDispatched).toBe(true);
expect(component.routerParams.id).toMatch('new-workbasket');
expect(component.showDetail).toBeTruthy();
expect(debugElement.nativeElement.querySelector('taskana-administration-workbasket-details')).toBeTruthy();
}));
});

View File

@ -1,28 +0,0 @@
import { Injectable } from '@angular/core';
import { Subject, Observable } from 'rxjs';
export class SavingInformation {
constructor(public url: string, public workbasketId: string) {}
}
@Injectable()
export class SavingWorkbasketService {
public distributionTargetsSavingInformation = new Subject<SavingInformation>();
public accessItemsSavingInformation = new Subject<SavingInformation>();
triggerDistributionTargetSaving(distributionTargetInformation: SavingInformation) {
this.distributionTargetsSavingInformation.next(distributionTargetInformation);
}
triggerAccessItemsSaving(accessItemsInformation: SavingInformation) {
this.accessItemsSavingInformation.next(accessItemsInformation);
}
triggeredDistributionTargetsSaving(): Observable<SavingInformation> {
return this.distributionTargetsSavingInformation.asObservable();
}
triggeredAccessItemsSaving(): Observable<SavingInformation> {
return this.accessItemsSavingInformation.asObservable();
}
}

View File

@ -39,6 +39,15 @@ export class WorkbasketSelectors {
};
}
@Selector([WorkbasketState])
static selectedWorkbasketAndComponentAndAction(state: WorkbasketStateModel): WorkbasketAndComponentAndAction {
return {
selectedWorkbasket: state.selectedWorkbasket,
action: state.action,
selectedComponent: state.selectedComponent
};
}
@Selector([WorkbasketState])
static selectedComponent(state: WorkbasketStateModel): WorkbasketComponent {
return state.selectedComponent;
@ -65,9 +74,20 @@ export class WorkbasketSelectors {
static availableDistributionTargets(state: WorkbasketStateModel): WorkbasketSummary[] {
return state.workbasketAvailableDistributionTargets;
}
@Selector([WorkbasketState])
static badgeMessage(state: WorkbasketStateModel): string {
return state.badgeMessage;
}
}
export interface WorkbasketAndAction {
selectedWorkbasket: Workbasket;
action: ACTION;
}
export interface WorkbasketAndComponentAndAction {
selectedWorkbasket: Workbasket;
action: ACTION;
selectedComponent: WorkbasketComponent;
}

View File

@ -1,5 +1,5 @@
import { Action, NgxsAfterBootstrap, State, StateContext } from '@ngxs/store';
import { take, tap } from 'rxjs/operators';
import { concatMap, take, tap } from 'rxjs/operators';
import { Observable, of } from 'rxjs';
import { Location } from '@angular/common';
import { WorkbasketService } from '../../services/workbasket/workbasket.service';
@ -34,6 +34,9 @@ import { WorkbasketComponent } from '../../../administration/models/workbasket-c
import { ButtonAction } from '../../../administration/models/button-action';
import { ActivatedRoute } from '@angular/router';
import { RequestInProgressService } from '../../services/request-in-progress/request-in-progress.service';
import { WorkbasketType } from '../../models/workbasket-type';
import { TaskanaDate } from '../../util/taskana.date';
import { DomainService } from '../../services/domain/domain.service';
class InitializeStore {
static readonly type = '[Workbasket] Initializing state';
@ -45,6 +48,7 @@ export class WorkbasketState implements NgxsAfterBootstrap {
private workbasketService: WorkbasketService,
private location: Location,
private notificationService: NotificationService,
private domainService: DomainService,
private route: ActivatedRoute,
private requestInProgressService: RequestInProgressService
) {}
@ -70,6 +74,10 @@ export class WorkbasketState implements NgxsAfterBootstrap {
tab = WorkbasketComponent.INFORMATION;
}
ctx.patchState({
badgeMessage: ''
});
ctx.dispatch(new SelectComponent(tab));
});
return of();
@ -105,12 +113,6 @@ export class WorkbasketState implements NgxsAfterBootstrap {
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(
@ -118,12 +120,20 @@ export class WorkbasketState implements NgxsAfterBootstrap {
tap((selectedWorkbasket) => {
ctx.patchState({
selectedWorkbasket,
action: ACTION.READ
action: ACTION.READ,
badgeMessage: ``
});
ctx.dispatch(new GetWorkbasketAccessItems(ctx.getState().selectedWorkbasket._links.accessItems.href));
ctx.dispatch(
new GetWorkbasketDistributionTargets(ctx.getState().selectedWorkbasket._links.distributionTargets.href)
);
this.location.go(
this.location
.path()
.replace(/(workbaskets).*/g, `workbaskets/(detail:${action.workbasketId})?tab=${selectedComponent}`)
);
})
);
}
@ -140,17 +150,6 @@ export class WorkbasketState implements NgxsAfterBootstrap {
return of(null);
}
@Action(CreateWorkbasket)
createWorkbasket(ctx: StateContext<WorkbasketStateModel>): Observable<any> {
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);
}
@Action(SetActiveAction)
setActiveAction(ctx: StateContext<WorkbasketStateModel>, action: SetActiveAction): Observable<any> {
ctx.patchState({ action: action.action });
@ -197,13 +196,13 @@ export class WorkbasketState implements NgxsAfterBootstrap {
new Map<string, string>([['workbasketKey', workbasketUpdated.key]])
);
ctx.dispatch(new SelectWorkbasket(workbasketUpdated.workbasketId));
this.location.go(this.location.path().replace(/(workbaskets).*/g, 'workbaskets'));
},
(error) => {
this.notificationService.triggerError(NOTIFICATION_TYPES.CREATE_ERR_2, error);
}
)
),
concatMap((workbasketUpdated) => ctx.dispatch(new SelectWorkbasket(workbasketUpdated.workbasketId)))
);
}
@ -211,12 +210,55 @@ export class WorkbasketState implements NgxsAfterBootstrap {
copyWorkbasket(ctx: StateContext<WorkbasketStateModel>, action: CopyWorkbasket): Observable<any> {
this.location.go(this.location.path().replace(/(workbaskets).*/g, 'workbaskets/(detail:new-workbasket)'));
ctx.dispatch(new OnButtonPressed(undefined));
const workbasket = { ...ctx.getState().selectedWorkbasket };
delete workbasket.workbasketId;
ctx.patchState({
action: ACTION.COPY
action: ACTION.COPY,
selectedWorkbasket: workbasket,
badgeMessage: `Copying workbasket: ${workbasket.key}`
});
return of(null);
}
@Action(CreateWorkbasket)
createWorkbasket(ctx: StateContext<WorkbasketStateModel>): Observable<any> {
return this.domainService.getSelectedDomain().pipe(
take(1),
tap((domain) => {
this.location.go(this.location.path().replace(/(workbaskets).*/g, 'workbaskets/(detail:new-workbasket)'));
if (!ctx.getState().workbasketAvailableDistributionTargets) {
ctx.dispatch(new GetAvailableDistributionTargets());
}
const emptyWorkbasket: Workbasket = {};
emptyWorkbasket.domain = domain;
emptyWorkbasket.type = WorkbasketType.PERSONAL;
const date = TaskanaDate.getDate();
emptyWorkbasket.created = date;
emptyWorkbasket.modified = date;
const accessItems = { accessItems: [], _links: {} };
const distributionTargets = { distributionTargets: [], _links: {} };
ctx.patchState({
action: ACTION.CREATE,
selectedWorkbasket: emptyWorkbasket,
selectedComponent: WorkbasketComponent.INFORMATION,
badgeMessage: `Creating new workbasket`,
workbasketAccessItems: accessItems,
workbasketDistributionTargets: distributionTargets
});
return of(null);
})
);
}
@Action(UpdateWorkbasket)
updateWorkbasket(ctx: StateContext<WorkbasketStateModel>, action: UpdateWorkbasket): Observable<any> {
ctx.dispatch(new OnButtonPressed(undefined));
@ -286,6 +328,8 @@ export class WorkbasketState implements NgxsAfterBootstrap {
NOTIFICATION_TYPES.SUCCESS_ALERT_12,
new Map<string, string>([['workbasketId', ctx.getState().selectedWorkbasket.workbasketId]])
);
ctx.dispatch(new DeselectWorkbasket());
}
})
);
@ -322,6 +366,7 @@ export class WorkbasketState implements NgxsAfterBootstrap {
NOTIFICATION_TYPES.SUCCESS_ALERT_7,
new Map<string, string>([['workbasketKey', ctx.getState().selectedWorkbasket.key]])
);
return of(null);
},
(error) => {
this.notificationService.triggerError(NOTIFICATION_TYPES.SAVE_ERR_2, error);
@ -385,6 +430,8 @@ export class WorkbasketState implements NgxsAfterBootstrap {
NOTIFICATION_TYPES.SUCCESS_ALERT_8,
new Map<string, string>([['workbasketName', ctx.getState().selectedWorkbasket.name]])
);
return of(null);
},
(error) => {
this.notificationService.triggerError(NOTIFICATION_TYPES.SAVE_ERR_3, error);
@ -420,5 +467,6 @@ export interface WorkbasketStateModel {
workbasketDistributionTargets: WorkbasketDistributionTargets;
workbasketAvailableDistributionTargets: WorkbasketSummary[];
selectedComponent: WorkbasketComponent;
badgeMessage: string;
button: ButtonAction | undefined;
}