From e7661dbc7def8d5995a500fc384a9cc9c32e32db Mon Sep 17 00:00:00 2001 From: Nacho Date: Mon, 20 Aug 2018 16:08:26 +0200 Subject: [PATCH] TSK-691 - Add snack bar meaningfull message when triying to save a workbasket and owner is not correctly validated. --- .../workbasket-information.component.ts | 433 +++++++++++------- .../services/forms/forms-validator.service.ts | 50 +- 2 files changed, 304 insertions(+), 179 deletions(-) diff --git a/web/src/app/administration/workbasket/details/information/workbasket-information.component.ts b/web/src/app/administration/workbasket/details/information/workbasket-information.component.ts index 8252d91d7..53a46bb8c 100644 --- a/web/src/app/administration/workbasket/details/information/workbasket-information.component.ts +++ b/web/src/app/administration/workbasket/details/information/workbasket-information.component.ts @@ -1,4 +1,12 @@ -import { Component, OnInit, Input, OnDestroy, OnChanges, SimpleChanges, ViewChild } from '@angular/core'; +import { + Component, + OnInit, + Input, + OnDestroy, + OnChanges, + SimpleChanges, + ViewChild +} from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; import { Subscription } from 'rxjs'; import { NgForm } from '@angular/forms'; @@ -12,7 +20,10 @@ import { TaskanaDate } from 'app/shared/util/taskana.date'; import { AlertService } from 'app/services/alert/alert.service'; import { ErrorModalService } from 'app/services/errorModal/error-modal.service'; -import { SavingWorkbasketService, SavingInformation } from 'app/administration/services/saving-workbaskets/saving-workbaskets.service'; +import { + SavingWorkbasketService, + SavingInformation +} from 'app/administration/services/saving-workbaskets/saving-workbaskets.service'; import { WorkbasketService } from 'app/services/workbasket/workbasket.service'; import { RequestInProgressService } from 'app/services/requestInProgress/request-in-progress.service'; import { CustomFieldsService } from 'app/services/custom-fields/custom-fields.service'; @@ -20,187 +31,283 @@ import { RemoveConfirmationService } from 'app/services/remove-confirmation/remo import { FormsValidatorService } from 'app/shared/services/forms/forms-validator.service'; @Component({ - selector: 'taskana-workbasket-information', - templateUrl: './workbasket-information.component.html', - styleUrls: ['./workbasket-information.component.scss'] + selector: 'taskana-workbasket-information', + templateUrl: './workbasket-information.component.html', + styleUrls: ['./workbasket-information.component.scss'] }) -export class WorkbasketInformationComponent implements OnInit, OnChanges, OnDestroy { +export class WorkbasketInformationComponent + implements OnInit, OnChanges, OnDestroy { + @Input() + workbasket: Workbasket; + workbasketClone: Workbasket; + workbasketErrors; + @Input() + action: string; + allTypes: Map; + requestInProgress = false; + badgeMessage = ''; - @Input() - workbasket: Workbasket; - workbasketClone: Workbasket; - workbasketErrors - @Input() - action: string; + ownerField = this.customFieldsService.getCustomField( + 'Owner', + 'workbaskets.information.owner' + ); + custom1Field = this.customFieldsService.getCustomField( + 'Custom 1', + 'workbaskets.information.custom1' + ); + custom2Field = this.customFieldsService.getCustomField( + 'Custom 2', + 'workbaskets.information.custom2' + ); + custom3Field = this.customFieldsService.getCustomField( + 'Custom 3', + 'workbaskets.information.custom3' + ); + custom4Field = this.customFieldsService.getCustomField( + 'Custom 4', + 'workbaskets.information.custom4' + ); - allTypes: Map; - requestInProgress = false; - badgeMessage = ''; + toogleValidationMap = new Map(); - ownerField = this.customFieldsService.getCustomField('Owner', 'workbaskets.information.owner'); - custom1Field = this.customFieldsService.getCustomField('Custom 1', 'workbaskets.information.custom1'); - custom2Field = this.customFieldsService.getCustomField('Custom 2', 'workbaskets.information.custom2'); - custom3Field = this.customFieldsService.getCustomField('Custom 3', 'workbaskets.information.custom3'); - custom4Field = this.customFieldsService.getCustomField('Custom 4', 'workbaskets.information.custom4'); - - toogleValidationMap = new Map(); - - private workbasketSubscription: Subscription; + private workbasketSubscription: Subscription; private routeSubscription: Subscription; - private savingValidationSubscription: Subscription; - @ViewChild('WorkbasketForm') workbasketForm: NgForm; + @ViewChild('WorkbasketForm') + workbasketForm: NgForm; - constructor(private workbasketService: WorkbasketService, - private alertService: AlertService, - private route: ActivatedRoute, - private router: Router, - private errorModalService: ErrorModalService, - private savingWorkbasket: SavingWorkbasketService, - private requestInProgressService: RequestInProgressService, - private customFieldsService: CustomFieldsService, - private removeConfirmationService: RemoveConfirmationService, - private formsValidatorService: FormsValidatorService) { - this.allTypes = new Map([['PERSONAL', 'Personal'], ['GROUP', 'Group'], - ['CLEARANCE', 'Clearance'], ['TOPIC', 'Topic']]) + constructor( + private workbasketService: WorkbasketService, + private alertService: AlertService, + private route: ActivatedRoute, + private router: Router, + private errorModalService: ErrorModalService, + private savingWorkbasket: SavingWorkbasketService, + private requestInProgressService: RequestInProgressService, + private customFieldsService: CustomFieldsService, + private removeConfirmationService: RemoveConfirmationService, + private formsValidatorService: FormsValidatorService + ) { + this.allTypes = new Map([ + ['PERSONAL', 'Personal'], + ['GROUP', 'Group'], + ['CLEARANCE', 'Clearance'], + ['TOPIC', 'Topic'] + ]); + } - } + ngOnInit(): void {} - ngOnInit(): void { - } + ngOnChanges(changes: SimpleChanges): void { + 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}`; + } + } - ngOnChanges(changes: SimpleChanges): void { - 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}`; - } - } + selectType(type: ICONTYPES) { + this.workbasket.type = type; + } - selectType(type: ICONTYPES) { - this.workbasket.type = type; - } + onSubmit() { + this.formsValidatorService.formSubmitAttempt = true; + this.formsValidatorService + .validateFormInformation(this.workbasketForm, this.toogleValidationMap) + .then(value => { + if (value) { + this.onSave(); + } + }); + } - onSubmit() { - this.formsValidatorService.formSubmitAttempt = true; - this.formsValidatorService.validateFormInformation(this.workbasketForm, this.toogleValidationMap).then(value => { - if (value) { - this.onSave(); - } + isFieldValid(field: string): boolean { + return this.formsValidatorService.isFieldValid(this.workbasketForm, field); + } + + onClear() { + this.formsValidatorService.formSubmitAttempt = false; + this.alertService.triggerAlert( + new AlertModel(AlertType.INFO, 'Reset edited fields') + ); + this.workbasket = { ...this.workbasketClone }; + } + + removeWorkbasket() { + this.removeConfirmationService.setRemoveConfirmation( + this.onRemoveConfirmed.bind(this), + `You are going to delete workbasket: ${ + this.workbasket.key + }. Can you confirm this action?` + ); + } + + copyWorkbasket() { + this.router.navigate([{ outlets: { detail: ['copy-workbasket'] } }], { + relativeTo: this.route.parent }); - } + } - isFieldValid(field: string): boolean { - return this.formsValidatorService.isFieldValid(this.workbasketForm, field); - } + removeDistributionTargets() { + this.requestInProgressService.setRequestInProgress(true); + this.workbasketService + .removeDistributionTarget( + this.workbasket._links.removeDistributionTargets.href + ) + .subscribe( + reponse => { + this.requestInProgressService.setRequestInProgress(false); + this.alertService.triggerAlert( + new AlertModel( + AlertType.SUCCESS, + `DistributionTarget for workbasketID: ${ + this.workbasket.workbasketId + } was removed successfully` + ) + ); + }, + error => { + this.errorModalService.triggerError( + new ErrorModel( + `There was an error removing distribution target for ${ + this.workbasket.workbasketId + }.`, + error + ) + ); + this.requestInProgressService.setRequestInProgress(false); + } + ); + } - onClear() { - this.formsValidatorService.formSubmitAttempt = false; - this.alertService.triggerAlert(new AlertModel(AlertType.INFO, 'Reset edited fields')) - this.workbasket = { ...this.workbasketClone }; - } + private onSave() { + this.beforeRequest(); + if (!this.workbasket.workbasketId) { + this.postNewWorkbasket(); + return true; + } - removeWorkbasket() { - this.removeConfirmationService.setRemoveConfirmation(this.onRemoveConfirmed.bind(this), - `You are going to delete workbasket: ${this.workbasket.key}. Can you confirm this action?`); - } + this.workbasketSubscription = this.workbasketService + .updateWorkbasket(this.workbasket._links.self.href, this.workbasket) + .subscribe( + workbasketUpdated => { + this.afterRequest(); + this.workbasket = workbasketUpdated; + this.workbasketClone = { ...this.workbasket }; + this.alertService.triggerAlert( + new AlertModel( + AlertType.SUCCESS, + `Workbasket ${workbasketUpdated.key} was saved successfully` + ) + ); + }, + error => { + this.afterRequest(); + this.errorModalService.triggerError( + new ErrorModel( + 'There was error while saving your workbasket', + error + ) + ); + } + ); + } - copyWorkbasket() { - this.router.navigate([{ outlets: { detail: ['copy-workbasket'] } }], { relativeTo: this.route.parent }); - } + private beforeRequest() { + this.requestInProgressService.setRequestInProgress(true); + } - removeDistributionTargets() { - this.requestInProgressService.setRequestInProgress(true); - this.workbasketService.removeDistributionTarget(this.workbasket._links.removeDistributionTargets.href).subscribe(reponse => { - this.requestInProgressService.setRequestInProgress(false); - this.alertService.triggerAlert( - new AlertModel(AlertType.SUCCESS, `DistributionTarget for workbasketID: ${this.workbasket.workbasketId} was removed successfully`)) - }, error => { - this.errorModalService.triggerError( - new ErrorModel(`There was an error removing distribution target for ${this.workbasket.workbasketId}.`, error)) - this.requestInProgressService.setRequestInProgress(false); - }); - } + private afterRequest() { + this.requestInProgressService.setRequestInProgress(false); + this.workbasketService.triggerWorkBasketSaved(); + } - private onSave() { - this.beforeRequest(); - if (!this.workbasket.workbasketId) { - this.postNewWorkbasket(); - return true; - } + private postNewWorkbasket() { + this.addDateToWorkbasket(); + this.workbasketService.createWorkbasket(this.workbasket).subscribe( + (workbasketUpdated: Workbasket) => { + this.alertService.triggerAlert( + new AlertModel( + AlertType.SUCCESS, + `Workbasket ${workbasketUpdated.key} was created successfully` + ) + ); + this.workbasket = workbasketUpdated; + this.afterRequest(); + this.workbasketService.triggerWorkBasketSaved(); + this.workbasketService.selectWorkBasket(this.workbasket.workbasketId); + this.router.navigate(['../' + this.workbasket.workbasketId], { + relativeTo: this.route + }); + 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 + ) + ); + } + }, + error => { + this.errorModalService.triggerError( + new ErrorModel('There was an error creating a workbasket', error) + ); + this.requestInProgressService.setRequestInProgress(false); + } + ); + } - this.workbasketSubscription = (this.workbasketService.updateWorkbasket(this.workbasket._links.self.href, this.workbasket).subscribe( - workbasketUpdated => { - this.afterRequest(); - this.workbasket = workbasketUpdated; - this.workbasketClone = { ...this.workbasket }; - this.alertService.triggerAlert(new AlertModel(AlertType.SUCCESS, `Workbasket ${workbasketUpdated.key} was saved successfully`)) - }, - error => { - this.afterRequest(); - this.errorModalService.triggerError(new ErrorModel('There was error while saving your workbasket', error)) - } - )); - } + private addDateToWorkbasket() { + const date = TaskanaDate.getDate(); + this.workbasket.created = date; + this.workbasket.modified = date; + } - private beforeRequest() { - this.requestInProgressService.setRequestInProgress(true); - } - - private afterRequest() { - this.requestInProgressService.setRequestInProgress(false); - this.workbasketService.triggerWorkBasketSaved(); - - } - - private postNewWorkbasket() { - this.addDateToWorkbasket(); - this.workbasketService.createWorkbasket(this.workbasket) - .subscribe((workbasketUpdated: Workbasket) => { - this.alertService.triggerAlert(new AlertModel(AlertType.SUCCESS, `Workbasket ${workbasketUpdated.key} was created successfully`)) - this.workbasket = workbasketUpdated; - this.afterRequest(); - this.workbasketService.triggerWorkBasketSaved(); - this.workbasketService.selectWorkBasket(this.workbasket.workbasketId); - this.router.navigate(['../' + this.workbasket.workbasketId], { relativeTo: this.route }); - 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)); - } - }, error => { - this.errorModalService.triggerError(new ErrorModel('There was an error creating a workbasket', error)) - this.requestInProgressService.setRequestInProgress(false); - }); - } - - private addDateToWorkbasket() { - const date = TaskanaDate.getDate(); - this.workbasket.created = date; - this.workbasket.modified = date; - } - - private onRemoveConfirmed() { - this.requestInProgressService.setRequestInProgress(true); - this.workbasketService.deleteWorkbasket(this.workbasket._links.self.href).subscribe(response => { - this.requestInProgressService.setRequestInProgress(false); - this.workbasketService.triggerWorkBasketSaved(); - this.alertService.triggerAlert(new AlertModel(AlertType.SUCCESS, - `Workbasket ${this.workbasket.workbasketId} was removed successfully`)) - this.router.navigate(['administration/workbaskets']); - }, error => { - this.requestInProgressService.setRequestInProgress(false); - this.errorModalService.triggerError(new ErrorModel( - `There was an error deleting workbasket ${this.workbasket.workbasketId}`, error)) - }); - } - - ngOnDestroy() { - if (this.workbasketSubscription) { this.workbasketSubscription.unsubscribe(); } - if (this.routeSubscription) { this.routeSubscription.unsubscribe(); } - if (this.savingValidationSubscription) { this.savingValidationSubscription.unsubscribe(); } - } + private onRemoveConfirmed() { + this.requestInProgressService.setRequestInProgress(true); + this.workbasketService + .deleteWorkbasket(this.workbasket._links.self.href) + .subscribe( + response => { + this.requestInProgressService.setRequestInProgress(false); + this.workbasketService.triggerWorkBasketSaved(); + this.alertService.triggerAlert( + new AlertModel( + AlertType.SUCCESS, + `Workbasket ${ + this.workbasket.workbasketId + } was removed successfully` + ) + ); + this.router.navigate(['administration/workbaskets']); + }, + error => { + this.requestInProgressService.setRequestInProgress(false); + this.errorModalService.triggerError( + new ErrorModel( + `There was an error deleting workbasket ${ + this.workbasket.workbasketId + }`, + error + ) + ); + } + ); + } + ngOnDestroy() { + if (this.workbasketSubscription) { + this.workbasketSubscription.unsubscribe(); + } + if (this.routeSubscription) { + this.routeSubscription.unsubscribe(); + } + } } diff --git a/web/src/app/shared/services/forms/forms-validator.service.ts b/web/src/app/shared/services/forms/forms-validator.service.ts index 48bc7a4e1..e779145cf 100644 --- a/web/src/app/shared/services/forms/forms-validator.service.ts +++ b/web/src/app/shared/services/forms/forms-validator.service.ts @@ -8,6 +8,7 @@ import { AccessIdsService } from 'app/shared/services/access-ids/access-ids.serv export class FormsValidatorService { public formSubmitAttempt = false; + private workbasketOwner = 'workbasket.owner'; constructor( private alertService: AlertService, @@ -29,26 +30,34 @@ export class FormsValidatorService { }); const ownerPromise = new Promise((resolve, reject) => { - if (form.form.controls['workbasket.owner']) { - this.accessIdsService.getAccessItemsInformation(form.form.controls['workbasket.owner'].value).subscribe(items => { - const validationState = toogleValidationMap.get('workbasket.owner'); - validationState ? toogleValidationMap.set('workbasket.owner', !validationState) : - toogleValidationMap.set('workbasket.owner', true); - items.find(item => item.accessId === form.form.controls['workbasket.owner'].value) ? resolve(true) : resolve(false); + const ownerString = 'owner'; + if (form.form.controls[this.workbasketOwner]) { + this.accessIdsService.getAccessItemsInformation(form.form.controls[this.workbasketOwner].value).subscribe(items => { + const validationState = toogleValidationMap.get(this.workbasketOwner); + validationState ? toogleValidationMap.set(this.workbasketOwner, !validationState) : + toogleValidationMap.set(this.workbasketOwner, true); + items.find(item => item.accessId === form.form.controls[this.workbasketOwner].value) ? + resolve(new ResponseOwner({valid: true, field: ownerString})) : + resolve(new ResponseOwner({valid: false, field: ownerString})); }); } else { - const validationState = toogleValidationMap.get(form.form.controls['workbasket.owner']); - validationState ? toogleValidationMap.set('workbasket.owner', !validationState) : - toogleValidationMap.set('workbasket.owner', true); - resolve(true); + const validationState = toogleValidationMap.get(form.form.controls[this.workbasketOwner]); + validationState ? toogleValidationMap.set(this.workbasketOwner, !validationState) : + toogleValidationMap.set(this.workbasketOwner, true); + resolve(new ResponseOwner({valid: true, field: ownerString})); } }); return Promise.all([forFieldsPromise, ownerPromise]).then(values => { - if (!(values[0] && values[1])) { - this.alertService.triggerAlert(new AlertModel(AlertType.WARNING, 'There are some empty fields which are required.')) + const responseOwner = new ResponseOwner(values[1]); + if (!(values[0] && responseOwner.valid)) { + if (!responseOwner.valid) { + this.alertService.triggerAlert(new AlertModel(AlertType.WARNING, 'The ' + responseOwner.field + ' introduced is not valid.')) + } else { + this.alertService.triggerAlert(new AlertModel(AlertType.WARNING, 'There are some empty fields which are required.')) + } } - return values[0] && values[1]; + return values[0] && responseOwner.valid; }); } @@ -61,18 +70,22 @@ export class FormsValidatorService { validationState ? toogleValidationAccessIdMap.set(i, !validationState) : toogleValidationAccessIdMap.set(i, true); this.accessIdsService.getAccessItemsInformation(form.controls[i].value['accessId']).subscribe(items => { - items.length > 0 ? resolve(true) : resolve(false); + items.length > 0 ? + resolve(new ResponseOwner({valid: true, field: 'access id'})) : + resolve(new ResponseOwner({valid: false, field: 'access id'})); }) })); } let result = true; return Promise.all(ownerPromise).then(values => { + let responseOwner; for (let i = 0; i < values.length; i++) { - result = result && values[i]; + responseOwner = new ResponseOwner(values[i]); + result = result && responseOwner.valid; } if (!result) { - this.alertService.triggerAlert(new AlertModel(AlertType.WARNING, 'There are some empty fields which are required.')) + this.alertService.triggerAlert(new AlertModel(AlertType.WARNING, 'The ' + responseOwner.field + ' introduced is not valid.')) } return result; }); @@ -89,3 +102,8 @@ export class FormsValidatorService { (ngForm.form.controls[field].touched && ngForm.form.controls[field].valid); } } + +function ResponseOwner(obj) { + this.valid = obj.valid; + this.field = obj.field; +}