+
* Owner is required
diff --git a/web/src/app/administration/workbasket/details/information/workbasket-information.component.scss b/web/src/app/administration/workbasket/details/information/workbasket-information.component.scss
index 20725ee04..b6f1bc259 100644
--- a/web/src/app/administration/workbasket/details/information/workbasket-information.component.scss
+++ b/web/src/app/administration/workbasket/details/information/workbasket-information.component.scss
@@ -1,3 +1,3 @@
.dropdown-menu {
min-width: auto;
-}
\ No newline at end of file
+}
diff --git a/web/src/app/administration/workbasket/details/information/workbasket-information.component.spec.ts b/web/src/app/administration/workbasket/details/information/workbasket-information.component.spec.ts
index 6f1f896b2..3042df4b9 100644
--- a/web/src/app/administration/workbasket/details/information/workbasket-information.component.spec.ts
+++ b/web/src/app/administration/workbasket/details/information/workbasket-information.component.spec.ts
@@ -1,13 +1,13 @@
-import { async, ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing';
+import { async, ComponentFixture, TestBed, fakeAsync } from '@angular/core/testing';
import { WorkbasketService } from 'app/services/workbasket/workbasket.service';
import { WorkbasketInformationComponent } from './workbasket-information.component';
-import { FormsModule, ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
+import { FormsModule } from '@angular/forms';
import { AngularSvgIconModule } from 'angular-svg-icon';
import { HttpClientModule } from '@angular/common/http';
import { HttpModule } from '@angular/http';
import { RouterTestingModule } from '@angular/router/testing';
import { Observable } from 'rxjs/Observable';
-import { Component, Input, forwardRef } from '@angular/core';
+import { Component } from '@angular/core';
import { Routes } from '@angular/router';
import { Workbasket } from 'app/models/workbasket';
@@ -18,11 +18,13 @@ import { Links } from 'app/models/links';
import { IconTypeComponent } from 'app/administration/components/type-icon/icon-type.component';
import { SpinnerComponent } from 'app/shared/spinner/spinner.component';
import { GeneralMessageModalComponent } from 'app/shared/general-message-modal/general-message-modal.component';
+import { TaskanaTypeAheadMockComponent } from 'app/shared/type-ahead/type-ahead.mock.component';
+
import { MapValuesPipe } from 'app/shared/pipes/mapValues/map-values.pipe';
import { RemoveNoneTypePipe } from 'app/shared/pipes/removeNoneType/remove-none-type.pipe';
import { ErrorModalService } from 'app/services/errorModal/error-modal.service';
-import { SavingWorkbasketService, SavingInformation } from 'app/administration/services/saving-workbaskets/saving-workbaskets.service';
+import { SavingWorkbasketService } from 'app/administration/services/saving-workbaskets/saving-workbaskets.service';
import { AlertService } from 'app/services/alert/alert.service';
import { RequestInProgressService } from 'app/services/requestInProgress/request-in-progress.service';
import { CustomFieldsService } from 'app/services/custom-fields/custom-fields.service';
@@ -35,36 +37,6 @@ import { configureTests } from 'app/app.test.configuration';
export class DummyDetailComponent {
}
-@Component({
- selector: 'taskana-type-ahead',
- template: 'dummydetail',
- providers: [
- {
- provide: NG_VALUE_ACCESSOR,
- multi: true,
- useExisting: forwardRef(() => TaskanaTypeAheadComponent),
- }
- ]
-})
-export class TaskanaTypeAheadComponent implements ControlValueAccessor {
- @Input()
- placeHolderMessage;
-
- writeValue(obj: any): void {
-
- }
- registerOnChange(fn: any): void {
-
- }
- registerOnTouched(fn: any): void {
-
- }
- setDisabledState?(isDisabled: boolean): void {
-
- }
-
-}
-
const routes: Routes = [
{ path: ':id', component: DummyDetailComponent, outlet: 'detail' },
{ path: 'someNewId', component: DummyDetailComponent }
@@ -80,7 +52,7 @@ describe('InformationComponent', () => {
testBed.configureTestingModule({
declarations: [WorkbasketInformationComponent, IconTypeComponent, MapValuesPipe,
RemoveNoneTypePipe, SpinnerComponent, GeneralMessageModalComponent, DummyDetailComponent,
- TaskanaTypeAheadComponent],
+ TaskanaTypeAheadMockComponent],
imports: [FormsModule,
AngularSvgIconModule,
HttpClientModule,
@@ -153,7 +125,7 @@ describe('InformationComponent', () => {
'orgLevel3', 'orgLevel4', new Links({ 'href': 'someUrl' }));
spyOn(workbasketService, 'updateWorkbasket').and.returnValue(Observable.of(component.workbasket));
spyOn(workbasketService, 'triggerWorkBasketSaved').and.returnValue(Observable.of(component.workbasket));
- component.onSave();
+ component.onSubmit();
expect(component.requestInProgress).toBeFalsy();
}));
@@ -164,7 +136,8 @@ describe('InformationComponent', () => {
'orgLevel3', 'orgLevel4', new Links({ 'href': 'someUrl' }));
spyOn(workbasketService, 'updateWorkbasket').and.returnValue(Observable.of(component.workbasket));
spyOn(workbasketService, 'triggerWorkBasketSaved').and.returnValue(Observable.of(component.workbasket));
- component.onSave();
+ fixture.detectChanges();
+ component.onSubmit();
expect(workbasketService.triggerWorkBasketSaved).toHaveBeenCalled();
});
@@ -177,8 +150,8 @@ describe('InformationComponent', () => {
new Workbasket('someNewId', 'created', 'keyModified', 'domain', ICONTYPES.TOPIC, 'modified', 'name', 'description',
'owner', 'custom1', 'custom2', 'custom3', 'custom4', 'orgLevel1', 'orgLevel2',
'orgLevel3', 'orgLevel4', new Links({ 'href': 'someUrl' }))));
-
- component.onSave();
+ fixture.detectChanges();
+ component.onSubmit();
expect(alertService.triggerAlert).toHaveBeenCalled();
expect(component.workbasket.workbasketId).toBe('someNewId');
});
@@ -199,8 +172,8 @@ describe('InformationComponent', () => {
spyOn(savingWorkbasketService, 'triggerDistributionTargetSaving');
spyOn(savingWorkbasketService, 'triggerAccessItemsSaving');
-
- component.onSave();
+ fixture.detectChanges();
+ component.onSubmit();
expect(alertService.triggerAlert).toHaveBeenCalled();
expect(component.workbasket.workbasketId).toBe('someNewId');
expect(savingWorkbasketService.triggerDistributionTargetSaving).toHaveBeenCalled();
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 e86a7ee8c..05905e6f6 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,6 +1,7 @@
-import { Component, OnInit, Input, OnDestroy, OnChanges, SimpleChanges } from '@angular/core';
+import { Component, OnInit, Input, OnDestroy, OnChanges, SimpleChanges, ViewChild } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { Subscription } from 'rxjs/Subscription';
+import { NgForm } from '@angular/forms';
import { ICONTYPES } from 'app/models/type';
import { ErrorModel } from 'app/models/modal-error';
@@ -16,9 +17,12 @@ 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';
import { RemoveConfirmationService } from 'app/services/remove-confirmation/remove-confirmation.service';
+import { highlight } from 'app/shared/animations/validation.animation';
+import { FormsValidatorService } from 'app/shared/services/forms/forms-validator.service';
@Component({
selector: 'taskana-workbasket-information',
+ animations: [highlight],
templateUrl: './workbasket-information.component.html',
styleUrls: ['./workbasket-information.component.scss']
})
@@ -28,6 +32,7 @@ export class WorkbasketInformationComponent implements OnInit, OnChanges, OnDest
@Input()
workbasket: Workbasket;
workbasketClone: Workbasket;
+ workbasketErrors
@Input()
action: string;
@@ -41,8 +46,11 @@ export class WorkbasketInformationComponent implements OnInit, OnChanges, OnDest
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 routeSubscription: Subscription;
+ @ViewChild('WorkbasketForm') workbasketForm: NgForm;
constructor(private workbasketService: WorkbasketService,
private alertService: AlertService,
@@ -52,7 +60,8 @@ export class WorkbasketInformationComponent implements OnInit, OnChanges, OnDest
private savingWorkbasket: SavingWorkbasketService,
private requestInProgressService: RequestInProgressService,
private customFieldsService: CustomFieldsService,
- private removeConfirmationService: RemoveConfirmationService) {
+ private removeConfirmationService: RemoveConfirmationService,
+ private formsValidatorService: FormsValidatorService) {
this.allTypes = new Map([['PERSONAL', 'Personal'], ['GROUP', 'Group'],
['CLEARANCE', 'Clearance'], ['TOPIC', 'Topic']])
@@ -75,7 +84,13 @@ export class WorkbasketInformationComponent implements OnInit, OnChanges, OnDest
this.workbasket.type = type;
}
- onSave() {
+ onSubmit() {
+ if (this.workbasketForm && this.formsValidatorService.validate(this.workbasketForm, this.toogleValidationMap)) {
+ this.onSave();
+ }
+ }
+
+ private onSave() {
this.beforeRequest();
if (!this.workbasket.workbasketId) {
this.postNewWorkbasket();
diff --git a/web/src/app/administration/workbasket/details/workbasket-details.component.spec.ts b/web/src/app/administration/workbasket/details/workbasket-details.component.spec.ts
index 28a486185..eb4a9296f 100644
--- a/web/src/app/administration/workbasket/details/workbasket-details.component.spec.ts
+++ b/web/src/app/administration/workbasket/details/workbasket-details.component.spec.ts
@@ -21,6 +21,10 @@ import { WorkbasketService } from 'app/services/workbasket/workbasket.service';
import { MasterAndDetailService } from 'app/services/masterAndDetail/master-and-detail.service';
import { AlertService } from 'app/services/alert/alert.service';
import { SavingWorkbasketService } from 'app/administration/services/saving-workbaskets/saving-workbaskets.service';
+import { ErrorModalService } from 'app/services/errorModal/error-modal.service';
+import { RequestInProgressService } from 'app/services/requestInProgress/request-in-progress.service';
+import { CustomFieldsService } from 'app/services/custom-fields/custom-fields.service';
+import { configureTests } from 'app/app.test.configuration';
import { WorkbasketDetailsComponent } from './workbasket-details.component';
import { WorkbasketInformationComponent } from './information/workbasket-information.component';
@@ -31,13 +35,14 @@ import { SpinnerComponent } from 'app/shared/spinner/spinner.component';
import { IconTypeComponent } from 'app/administration/components/type-icon/icon-type.component';
import { AlertComponent } from 'app/shared/alert/alert.component';
import { GeneralMessageModalComponent } from 'app/shared/general-message-modal/general-message-modal.component';
+import { TaskanaTypeAheadMockComponent } from 'app/shared/type-ahead/type-ahead.mock.component';
+
import { MapValuesPipe } from 'app/shared/pipes/mapValues/map-values.pipe';
import { RemoveNoneTypePipe } from 'app/shared/pipes/removeNoneType/remove-none-type.pipe';
import { SelectWorkBasketPipe } from 'app/shared/pipes/selectedWorkbasket/seleted-workbasket.pipe';
-import { ErrorModalService } from 'app/services/errorModal/error-modal.service';
-import { RequestInProgressService } from 'app/services/requestInProgress/request-in-progress.service';
-import { CustomFieldsService } from 'app/services/custom-fields/custom-fields.service';
-import { configureTests } from 'app/app.test.configuration';
+
+
+
@Component({
selector: 'taskana-filter',
template: ''
@@ -55,37 +60,6 @@ export class FilterComponent {
export class DummyDetailComponent {
}
-@Component({
- selector: 'taskana-type-ahead',
- template: 'dummydetail',
- providers: [
- {
- provide: NG_VALUE_ACCESSOR,
- multi: true,
- useExisting: forwardRef(() => TaskanaTypeAheadComponent),
- }
- ]
-})
-export class TaskanaTypeAheadComponent implements ControlValueAccessor {
-
- @Input()
- placeHolderMessage;
-
- writeValue(obj: any): void {
-
- }
- registerOnChange(fn: any): void {
-
- }
- registerOnTouched(fn: any): void {
-
- }
- setDisabledState?(isDisabled: boolean): void {
-
- }
-
-}
-
describe('WorkbasketDetailsComponent', () => {
let component: WorkbasketDetailsComponent;
let fixture: ComponentFixture;
@@ -107,7 +81,7 @@ describe('WorkbasketDetailsComponent', () => {
declarations: [WorkbasketDetailsComponent, WorkbasketInformationComponent, SpinnerComponent,
IconTypeComponent, MapValuesPipe, RemoveNoneTypePipe, AlertComponent, GeneralMessageModalComponent, AccessItemsComponent,
DistributionTargetsComponent, FilterComponent, DualListComponent, DummyDetailComponent,
- TaskanaTypeAheadComponent, SelectWorkBasketPipe],
+ TaskanaTypeAheadMockComponent, SelectWorkBasketPipe],
providers: [WorkbasketService, MasterAndDetailService, ErrorModalService, RequestInProgressService,
AlertService, SavingWorkbasketService,
CustomFieldsService]
diff --git a/web/src/app/administration/workbasket/master/list/workbasket-list-toolbar/workbasket-list-toolbar.component.html b/web/src/app/administration/workbasket/master/list/workbasket-list-toolbar/workbasket-list-toolbar.component.html
index 6c5b51fb0..2e65c0d8d 100644
--- a/web/src/app/administration/workbasket/master/list/workbasket-list-toolbar/workbasket-list-toolbar.component.html
+++ b/web/src/app/administration/workbasket/master/list/workbasket-list-toolbar/workbasket-list-toolbar.component.html
@@ -17,7 +17,7 @@