From 42197bee6c0e4014ba828f15d13d81b08161b324 Mon Sep 17 00:00:00 2001 From: Martin Rojas Miguel Angel Date: Mon, 9 Jul 2018 14:44:12 +0200 Subject: [PATCH] TSK-611 Add validation form errors on save - Add custom form validation on save with highlighting animation and snack bar warning - Added validation for classifications, workbaskets information and access items. - Enable save button always - Refactored animations - Test configuration cleanup --- .../classification-details.component.html | 6 +- .../classification-details.component.ts | 20 ++++++- .../access-items/access-items.component.html | 52 +++++++++--------- .../access-items.component.spec.ts | 39 ++----------- .../access-items/access-items.component.ts | 50 +++++++++++------ .../dual-list/dual-list.component.html | 2 +- .../dual-list/dual-list.component.ts | 18 +----- .../workbasket-information.component.html | 13 ++--- .../workbasket-information.component.scss | 2 +- .../workbasket-information.component.spec.ts | 55 +++++-------------- .../workbasket-information.component.ts | 21 ++++++- .../workbasket-details.component.spec.ts | 46 ++++------------ .../workbasket-list-toolbar.component.html | 2 +- .../workbasket-list-toolbar.component.ts | 19 +------ web/src/app/app.test.configuration.ts | 5 +- web/src/app/app.test.module.ts | 17 ++++++ .../components/nav-bar/nav-bar.component.html | 2 +- .../components/nav-bar/nav-bar.component.ts | 15 +---- .../taskana-engine.mock.service.ts | 4 -- web/src/app/shared/alert/alert.component.html | 2 +- web/src/app/shared/alert/alert.component.ts | 15 +---- .../app/shared/animations/expand.animation.ts | 51 +++++++++++++++++ .../shared/animations/validation.animation.ts | 12 ++++ .../services/forms/forms-validator.service.ts | 25 +++++++++ web/src/app/shared/shared.module.ts | 6 +- .../type-ahead/type-ahead.component.html | 3 +- .../type-ahead/type-ahead.component.scss | 18 ++++++ .../shared/type-ahead/type-ahead.component.ts | 10 ++-- .../type-ahead/type-ahead.mock.component.ts | 34 ++++++++++++ .../components/code/code.component.ts | 16 +----- web/src/assets/_forms.scss | 2 +- 31 files changed, 322 insertions(+), 260 deletions(-) create mode 100644 web/src/app/app.test.module.ts create mode 100644 web/src/app/shared/animations/expand.animation.ts create mode 100644 web/src/app/shared/animations/validation.animation.ts create mode 100644 web/src/app/shared/services/forms/forms-validator.service.ts create mode 100644 web/src/app/shared/type-ahead/type-ahead.mock.component.ts diff --git a/web/src/app/administration/classification/details/classification-details.component.html b/web/src/app/administration/classification/details/classification-details.component.html index 49be99ba5..c4706337b 100644 --- a/web/src/app/administration/classification/details/classification-details.component.html +++ b/web/src/app/administration/classification/details/classification-details.component.html @@ -11,7 +11,7 @@
- @@ -33,7 +33,7 @@ -
+
* Key is required
@@ -41,7 +41,7 @@ -
+
* Name is required
diff --git a/web/src/app/administration/classification/details/classification-details.component.ts b/web/src/app/administration/classification/details/classification-details.component.ts index 9dba45301..7b416b1d4 100644 --- a/web/src/app/administration/classification/details/classification-details.component.ts +++ b/web/src/app/administration/classification/details/classification-details.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, OnDestroy } from '@angular/core'; +import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; import { Subscription } from 'rxjs/Subscription'; @@ -7,6 +7,7 @@ import { ACTION } from 'app/models/action'; import { ErrorModel } from 'app/models/modal-error'; import { AlertModel, AlertType } from 'app/models/alert'; +import { highlight } from 'app/shared/animations/validation.animation'; import { TaskanaDate } from 'app/shared/util/taskana.date'; import { ClassificationsService } from 'app/administration/services/classifications/classifications.service'; @@ -24,10 +25,13 @@ import { ClassificationCategoriesService } from 'app/administration/services/cla import { DomainService } from 'app/services/domain/domain.service'; import { CustomFieldsService } from '../../../services/custom-fields/custom-fields.service'; import { Pair } from 'app/models/pair'; +import { NgForm } from '@angular/forms'; +import { FormsValidatorService } from 'app/shared/services/forms/forms-validator.service'; @Component({ selector: 'taskana-classification-details', templateUrl: './classification-details.component.html', + animations: [highlight], styleUrls: ['./classification-details.component.scss'] }) export class ClassificationDetailsComponent implements OnInit, OnDestroy { @@ -62,6 +66,9 @@ export class ClassificationDetailsComponent implements OnInit, OnDestroy { private categoriesSubscription: Subscription; private domainSubscription: Subscription; + @ViewChild('ClassificationForm') classificationForm: NgForm; + toogleValidationMap = new Map(); + constructor(private classificationsService: ClassificationsService, private route: ActivatedRoute, private router: Router, @@ -74,7 +81,8 @@ export class ClassificationDetailsComponent implements OnInit, OnDestroy { private categoryService: ClassificationCategoriesService, private domainService: DomainService, private customFieldsService: CustomFieldsService, - private removeConfirmationService: RemoveConfirmationService) { } + private removeConfirmationService: RemoveConfirmationService, + private formsValidatorService: FormsValidatorService) { } ngOnInit() { this.classificationTypeService.getClassificationTypes().subscribe((classificationTypes: Array) => { @@ -133,7 +141,13 @@ export class ClassificationDetailsComponent implements OnInit, OnDestroy { `You are going to delete classification: ${this.classification.key}. Can you confirm this action?`); } - onSave() { + onSubmit() { + if (this.formsValidatorService.validate(this.classificationForm, this.toogleValidationMap)) { + this.onSave(); + } + } + + private onSave() { this.requestInProgressService.setRequestInProgress(true); if (this.action === ACTION.CREATE) { this.classificationSavingSubscription = this.classificationsService.postClassification(this.classification) diff --git a/web/src/app/administration/workbasket/details/access-items/access-items.component.html b/web/src/app/administration/workbasket/details/access-items/access-items.component.html index e1001c9d2..05b0fa29b 100644 --- a/web/src/app/administration/workbasket/details/access-items/access-items.component.html +++ b/web/src/app/administration/workbasket/details/access-items/access-items.component.html @@ -1,8 +1,8 @@
-
-
+
diff --git a/web/src/app/administration/workbasket/details/distribution-targets/dual-list/dual-list.component.ts b/web/src/app/administration/workbasket/details/distribution-targets/dual-list/dual-list.component.ts index 768ebbb3e..206cb9939 100644 --- a/web/src/app/administration/workbasket/details/distribution-targets/dual-list/dual-list.component.ts +++ b/web/src/app/administration/workbasket/details/distribution-targets/dual-list/dual-list.component.ts @@ -1,28 +1,14 @@ import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core'; import { WorkbasketSummary } from 'app/models/workbasket-summary'; -import { trigger, state, style, transition, animate, keyframes } from '@angular/animations'; import { FilterModel } from 'app/models/filter'; -import { filter } from 'rxjs/operators'; import { Side } from '../distribution-targets.component'; +import { expandDown } from 'app/shared/animations/expand.animation'; @Component({ selector: 'taskana-dual-list', templateUrl: './dual-list.component.html', styleUrls: ['./dual-list.component.scss'], - animations: [ - trigger('toggle', [ - state('*', style({ opacity: '1' })), - state('void', style({ opacity: '0' })), - transition('void => *', animate('300ms ease-in', keyframes([ - style({ opacity: 0, height: '0px' }), - style({ opacity: 0.5, height: '50px' }), - style({ opacity: 1, height: '*' })]))), - transition('* => void', animate('300ms ease-out', keyframes([ - style({ opacity: 1, height: '*' }), - style({ opacity: 0.5, height: '50px' }), - style({ opacity: 0, height: '0px' })]))) - ] - )], + animations: [expandDown] }) export class DualListComponent implements OnInit { diff --git a/web/src/app/administration/workbasket/details/information/workbasket-information.component.html b/web/src/app/administration/workbasket/details/information/workbasket-information.component.html index 41539375b..f56a65979 100644 --- a/web/src/app/administration/workbasket/details/information/workbasket-information.component.html +++ b/web/src/app/administration/workbasket/details/information/workbasket-information.component.html @@ -2,8 +2,7 @@
-
-