TSK-192 include ngForm validations for workbasket information and access items

This commit is contained in:
Martin Rojas Miguel Angel 2018-03-06 15:52:52 +01:00 committed by Holger Hagen
parent d25e846fd5
commit 4a2476360d
12 changed files with 256 additions and 234 deletions

View File

@ -20,7 +20,8 @@
"prefix": "app",
"styles": [
"../node_modules/bootstrap-sass/assets/stylesheets/_bootstrap.scss",
"./assets/_site.scss"
"./assets/_site.scss",
"./assets/_forms.scss"
],
"scripts": ["../node_modules/jquery/dist/jquery.min.js","../node_modules/bootstrap/dist/js/bootstrap.min.js"],
"environmentSource": "environments/environment.ts",

View File

@ -3,7 +3,7 @@
*/
import { BrowserModule } from '@angular/platform-browser';
import { NgModule, } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
import { AppRoutingModule } from './app-routing.module';
import { AlertModule } from 'ngx-bootstrap';
@ -61,7 +61,8 @@ const MODULES = [
AlertModule.forRoot(),
AngularSvgIconModule,
HttpClientModule,
BrowserAnimationsModule
BrowserAnimationsModule,
ReactiveFormsModule
];
const DECLARATIONS = [

View File

@ -3,13 +3,14 @@
<div *ngIf="workbasket" id="wb-information" class="panel panel-default">
<div class="panel-heading">
<div class="btn-group pull-right">
<button type="button" (click)="onSave()" class="btn btn-default btn-primary">Save</button>
<button type="button" (click)="onSave()" [disabled]="!AccessItemsForm.form.valid" class="btn btn-default btn-primary">Save</button>
<button type="button" (click)="clear()" class="btn btn-default">Undo changes</button>
</div>
<h4 class="panel-header">{{workbasket.name}}</h4>
</div>
<div class="panel-body">
<table id="table-access-items"class="table table-striped table-center">
<form #AccessItemsForm="ngForm">
<table id="table-access-items" class="table table-striped table-center">
<thead>
<tr>
<th></th>
@ -34,76 +35,79 @@
</tr>
</thead>
<tbody>
<tr *ngFor="let authorization of accessItems; let index = index;">
<tr *ngFor="let accessItem of accessItems; let index = index;" ngModelGroup="accessItems">
<td>
<button type="button" (click)="remove(index)" data-toggle="tooltip" title="Remove" class="btn btn-default remove">
<span class="glyphicon glyphicon-remove" aria-hidden="true"></span>
</button>
</td>
<td class="text-align text-width ">
<div class ="input-group"
[ngClass]="{
'has-warning': (accessItemsClone[index].accessId !== authorization.accessId),
'has-error': !authorization.accessId }">
<input type="text" class="form-control" [(ngModel)]="authorization.accessId">
<div class="input-group" [ngClass]="{
'has-warning': (accessItemsClone[index].accessId !== accessItem.accessId),
'has-error': !accessItem.accessId }">
<input type="text" required #accessItemName="ngModel" class="form-control" name="accessItem.accessId-{{index}}" [(ngModel)]="accessItem.accessId" placeholder="{{accessItemName.invalid? 'Access id is required': ''}}">
</div>
</td>
<td [ngClass]="{'has-changes': (accessItemsClone[index].permRead !== authorization.permRead)}">
<input type="checkbox" disabled="disabled" [(ngModel)]="authorization.permRead">
<td [ngClass]="{'has-changes': (accessItemsClone[index].permRead !== accessItem.permRead)}">
<input type="checkbox" disabled="disabled" name="accessItem.permRead-{{index}}" [(ngModel)]="accessItem.permRead">
</td>
<td [ngClass]="{'has-changes': (accessItemsClone[index].permOpen !== authorization.permOpen)}">
<input type="checkbox" [(ngModel)]="authorization.permOpen">
<td [ngClass]="{'has-changes': (accessItemsClone[index].permOpen !== accessItem.permOpen)}">
<input type="checkbox" name="accessItem.permOpen-{{index}}" [(ngModel)]="accessItem.permOpen">
</td>
<td [ngClass]="{'has-changes': (accessItemsClone[index].permAppend !== authorization.permAppend)}">
<input type="checkbox" [(ngModel)]="authorization.permAppend">
<td [ngClass]="{'has-changes': (accessItemsClone[index].permAppend !== accessItem.permAppend)}">
<input type="checkbox" name="accessItem.permAppend-{{index}}" [(ngModel)]="accessItem.permAppend">
</td>
<td [ngClass]="{'has-changes': (accessItemsClone[index].permTransfer !== authorization.permTransfer)}">
<input type="checkbox" [(ngModel)]="authorization.permTransfer">
<td [ngClass]="{'has-changes': (accessItemsClone[index].permTransfer != accessItem.permTransfer)}">
<input type="checkbox" name="accessItem.permTransfer-{{index}}" [(ngModel)]="accessItem.permTransfer">
</td>
<td [ngClass]="{'has-changes': (accessItemsClone[index].permDistribute !== authorization.permDistribute)}">
<input type="checkbox" [(ngModel)]="authorization.permDistribute">
<td [ngClass]="{'has-changes': (accessItemsClone[index].permDistribute !== accessItem.permDistribute)}">
<input type="checkbox" name="accessItem.permDistribute-{{index}}" [(ngModel)]="accessItem.permDistribute">
</td>
<td [ngClass]="{'has-changes': (accessItemsClone[index].permCustom1 !== authorization.permCustom1)}">
<input type="checkbox" [(ngModel)]="authorization.permCustom1">
<td [ngClass]="{'has-changes': (accessItemsClone[index].permCustom1 !== accessItem.permCustom1)}">
<input type="checkbox" name="accessItem.permCustom1-{{index}}" [(ngModel)]="accessItem.permCustom1">
</td>
<td [ngClass]="{'has-changes': (accessItemsClone[index].permCustom2 !== authorization.permCustom2)}">
<input type="checkbox" [(ngModel)]="authorization.permCustom2">
<td [ngClass]="{'has-changes': (accessItemsClone[index].permCustom2 !== accessItem.permCustom2)}">
<input type="checkbox" name="accessItem.permCustom2-{{index}}" [(ngModel)]="accessItem.permCustom2">
</td>
<td [ngClass]="{'has-changes': (accessItemsClone[index].permCustom3 !== authorization.permCustom3)}">
<input type="checkbox" [(ngModel)]="authorization.permCustom3">
<td [ngClass]="{'has-changes': (accessItemsClone[index].permCustom3 !== accessItem.permCustom3)}">
<input type="checkbox" name="accessItem.permCustom3-{{index}}" [(ngModel)]="accessItem.permCustom3">
</td>
<td [ngClass]="{'has-changes': (accessItemsClone[index].permCustom4 !== authorization.permCustom4)}">
<input type="checkbox" [(ngModel)]="authorization.permCustom4">
<td [ngClass]="{'has-changes': (accessItemsClone[index].permCustom4 !== accessItem.permCustom4)}">
<input type="checkbox" name="accessItem.permCustom4-{{index}}" [(ngModel)]="accessItem.permCustom4">
</td>
<td [ngClass]="{'has-changes': (accessItemsClone[index].permCustom5 !== authorization.permCustom5)}">
<input type="checkbox" [(ngModel)]="authorization.permCustom5">
<td [ngClass]="{'has-changes': (accessItemsClone[index].permCustom5 !== accessItem.permCustom5)}">
<input type="checkbox" name="accessItem.permCustom5-{{index}}" [(ngModel)]="accessItem.permCustom5">
</td>
<td [ngClass]="{'has-changes': (accessItemsClone[index].permCustom6 !== authorization.permCustom6)}">
<input type="checkbox" [(ngModel)]="authorization.permCustom6">
<td [ngClass]="{'has-changes': (accessItemsClone[index].permCustom6 !== accessItem.permCustom6)}">
<input type="checkbox" name="accessItem.permCustom6-{{index}}" [(ngModel)]="accessItem.permCustom6">
</td>
<td [ngClass]="{'has-changes': (accessItemsClone[index].permCustom7 !== authorization.permCustom7)}">
<input type="checkbox" [(ngModel)]="authorization.permCustom7">
<td [ngClass]="{'has-changes': (accessItemsClone[index].permCustom7 !== accessItem.permCustom7)}">
<input type="checkbox" name="accessItem.permCustom7-{{index}}" [(ngModel)]="accessItem.permCustom7">
</td>
<td [ngClass]="{'has-changes': (accessItemsClone[index].permCustom8 !== authorization.permCustom8)}">
<input type="checkbox" [(ngModel)]="authorization.permCustom8">
<td [ngClass]="{'has-changes': (accessItemsClone[index].permCustom8 !== accessItem.permCustom8)}">
<input type="checkbox" name="accessItem.permCustom8-{{index}}" [(ngModel)]="accessItem.permCustom8">
</td>
<td [ngClass]="{'has-changes': (accessItemsClone[index].permCustom9 !== authorization.permCustom9)}">
<input type="checkbox" [(ngModel)]="authorization.permCustom9">
<td [ngClass]="{'has-changes': (accessItemsClone[index].permCustom9 !== accessItem.permCustom9)}">
<input type="checkbox" name="accessItem.permCustom9-{{index}}" [(ngModel)]="accessItem.permCustom9">
</td>
<td [ngClass]="{'has-changes': (accessItemsClone[index].permCustom10 !== authorization.permCustom10)}">
<input type="checkbox" [(ngModel)]="authorization.permCustom10">
<td [ngClass]="{'has-changes': (accessItemsClone[index].permCustom10 !== accessItem.permCustom10)}">
<input type="checkbox" name="accessItem.permCustom10-{{index}}" [(ngModel)]="accessItem.permCustom10">
</td>
<td [ngClass]="{'has-changes': (accessItemsClone[index].permCustom11 !== authorization.permCustom11)}">
<input type="checkbox" [(ngModel)]="authorization.permCustom11">
<td [ngClass]="{'has-changes': (accessItemsClone[index].permCustom11 !== accessItem.permCustom11)}">
<input type="checkbox" name="accessItem.permCustom11-{{index}}" [(ngModel)]="accessItem.permCustom11">
</td>
<td [ngClass]="{'has-changes': (accessItemsClone[index].permCustom12 !== authorization.permCustom12)}">
<input type="checkbox" [(ngModel)]="authorization.permCustom12">
<td [ngClass]="{'has-changes': (accessItemsClone[index].permCustom12 !== accessItem.permCustom12)}">
<input type="checkbox" name="accessItem.permCustom12-{{index}}" [(ngModel)]="accessItem.permCustom12">
</td>
</tr>
</tbody>
</table>
</form>
<button id="button-add-access-item" type="button" (click)="addAccessItem()" class="btn btn-default">
<span><svg-icon class="green small" src="./assets/icons/wb-add.svg"></svg-icon></span>
<span>
<svg-icon class="green small" src="./assets/icons/wb-add.svg"></svg-icon>
</span>
Add new access
</button>
</div>

View File

@ -5,7 +5,7 @@ td > input[type="checkbox"] {
overflow-x: auto;
}
.text-width{
min-width: 150px;
min-width: 180px;
}
.required-header:after {
content:" *";

View File

@ -1,12 +1,12 @@
import { async, ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing';
import { WorkbasketService } from '../../../services/workbasket.service';
import { FormsModule } from '@angular/forms';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { AngularSvgIconModule } from 'angular-svg-icon';
import { HttpClientModule } from '@angular/common/http';
import { HttpModule, JsonpModule } from '@angular/http';
import { Workbasket } from 'app/model/workbasket';
import { SpinnerComponent } from '../../../shared/spinner/spinner.component';
import { AlertService, AlertModel , AlertType } from '../../../services/alert.service';
import { AlertService, AlertModel, AlertType } from '../../../services/alert.service';
import { GeneralMessageModalComponent } from '../../../shared/general-message-modal/general-message-modal.component';
import { Links } from '../../../model/links';
import { Observable } from 'rxjs/Observable';
@ -21,7 +21,7 @@ describe('AccessItemsComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [SpinnerComponent, AccessItemsComponent, GeneralMessageModalComponent],
imports: [FormsModule, AngularSvgIconModule, HttpClientModule, HttpModule],
imports: [FormsModule, AngularSvgIconModule, HttpClientModule, HttpModule, ReactiveFormsModule],
providers: [WorkbasketService, AlertService]
})
@ -34,7 +34,7 @@ describe('AccessItemsComponent', () => {
component.workbasket = new Workbasket('1')
workbasketService = TestBed.get(WorkbasketService);
alertService = TestBed.get(AlertService);
spyOn(workbasketService, 'getWorkBasketAccessItems').and.returnValue(Observable.of(new Array<WorkbasketAccessItems>(new WorkbasketAccessItems('id1', '1', 'accessID1', false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, new Array<Links>(new Links('setWorkbasketAccessItems',''))),
spyOn(workbasketService, 'getWorkBasketAccessItems').and.returnValue(Observable.of(new Array<WorkbasketAccessItems>(new WorkbasketAccessItems('id1', '1', 'accessID1', false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, new Array<Links>(new Links('setWorkbasketAccessItems', ''))),
new WorkbasketAccessItems('id2', '1', 'accessID2'))));
spyOn(workbasketService, 'updateWorkBasketAccessItem').and.returnValue(Observable.of(true)),
spyOn(alertService, 'triggerAlert').and.returnValue(Observable.of(true)),
@ -65,19 +65,22 @@ describe('AccessItemsComponent', () => {
expect(debugElement.querySelectorAll('#table-access-items > tbody > tr')[0].querySelectorAll('td')[5].getAttribute('class')).toBeNull();
debugElement.querySelectorAll('#table-access-items > tbody > tr')[0].querySelectorAll('td')[5].querySelector('input').click();
fixture.detectChanges();
component
fixture.whenStable().then(() => {
expect(debugElement.querySelectorAll('#table-access-items > tbody > tr')[0].querySelectorAll('td')[5].getAttribute('class')).toBe('has-changes');
});
});
it('should undo changes if undo changes button is clicked', () => {
debugElement.querySelectorAll('#table-access-items > tbody > tr')[0].querySelectorAll('td')[5].querySelector('input').click();
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(debugElement.querySelectorAll('#table-access-items > tbody > tr')[0].querySelectorAll('td')[5].getAttribute('class')).toBe('has-changes');
expect(debugElement.querySelectorAll('#wb-information > div > div')[0].querySelectorAll('button').length).toBe(2);
debugElement.querySelectorAll('#wb-information > div > div')[0].querySelectorAll('button')[1].click();
fixture.detectChanges();
expect(debugElement.querySelectorAll('#table-access-items > tbody > tr')[0].querySelectorAll('td')[5].getAttribute('class')).toBeNull();
});
});
it('should remove an access item if remove button is clicked', () => {
expect(debugElement.querySelectorAll('#table-access-items > tbody > tr').length).toBe(2);
@ -86,16 +89,6 @@ describe('AccessItemsComponent', () => {
expect(debugElement.querySelectorAll('#table-access-items > tbody > tr').length).toBe(1);
});
it('should validate access-items before saving', () => {
debugElement.querySelector('#button-add-access-item').click();
fixture.detectChanges();
expect(component.onSave()).toBeUndefined();
component.accessItems[2].accessId = 'someText';
component.onSave();
expect(workbasketService.updateWorkBasketAccessItem).toHaveBeenCalled();
});
it('should show alert successfull after saving', () => {
component.onSave();
expect(alertService.triggerAlert).toHaveBeenCalledWith(new AlertModel(AlertType.SUCCESS, `Workbasket ${component.workbasket.key} Access items were saved successfully`));

View File

@ -35,8 +35,8 @@ export class AccessItemsComponent implements OnInit {
ngOnInit() {
this.accessItemsubscription = this.workbasketService.getWorkBasketAccessItems(this.workbasket.workbasketId).subscribe( (accessItems: Array<WorkbasketAccessItems>) =>{
this.accessItems = accessItems;
this.accessItemsClone = this.cloneaccessItems(this.accessItems);
this.accessItemsResetClone = this.cloneaccessItems(this.accessItems);
this.accessItemsClone = this.cloneAccessItems(this.accessItems);
this.accessItemsResetClone = this.cloneAccessItems(this.accessItems);
})
}
@ -47,8 +47,9 @@ export class AccessItemsComponent implements OnInit {
}
clear() {
this.accessItems = this.cloneaccessItems(this.accessItemsResetClone);
this.accessItemsClone = this.cloneaccessItems(this.accessItemsResetClone);
this.alertService.triggerAlert(new AlertModel(AlertType.INFO, 'Reset edited fields'))
this.accessItems = this.cloneAccessItems(this.accessItemsResetClone);
this.accessItemsClone = this.cloneAccessItems(this.accessItemsResetClone);
}
remove(index: number) {
@ -57,17 +58,14 @@ export class AccessItemsComponent implements OnInit {
}
onSave(): boolean {
if(this.validateAccessItems()){
return;
}
if(!this.accessItems[0].links){
return;
}
this.workbasketService.updateWorkBasketAccessItem(Utils.getTagLinkRef(this.accessItems[0].links, 'setWorkbasketAccessItems').href, this.accessItems).subscribe(response =>{
this.accessItemsClone = this.cloneaccessItems(this.accessItems);
this.accessItemsResetClone = this.cloneaccessItems(this.accessItems);
this.alertService.triggerAlert(new AlertModel(AlertType.SUCCESS, `Workbasket ${this.workbasket.key} Access items were saved successfully`));
this.accessItemsClone = this.cloneAccessItems(this.accessItems);
this.accessItemsResetClone = this.cloneAccessItems(this.accessItems);
this.alertService.triggerAlert(new AlertModel(AlertType.SUCCESS, `Workbasket ${this.workbasket.name} Access items were saved successfully`));
return true;
},
error => {
@ -76,25 +74,14 @@ export class AccessItemsComponent implements OnInit {
})
}
private validateAccessItems(): boolean {
return this.accessItems.some(element => {
if(!element.accessId || element.accessId === '') {
this.showValidationError();
return true;
}
});
}
setValue() { debugger; }
private showValidationError() {
this.alertService.triggerAlert(new AlertModel(AlertType.DANGER, "AccessId must not be empty", false));
}
private cloneaccessItems(inputAuthorization): Array<WorkbasketAccessItems>{
let authorizationClone = new Array<WorkbasketAccessItems>();
inputAuthorization.forEach(authorization => {
authorizationClone.push({... authorization});
private cloneAccessItems(inputaccessItem): Array<WorkbasketAccessItems>{
let accessItemClone = new Array<WorkbasketAccessItems>();
inputaccessItem.forEach(accessItem => {
accessItemClone.push({... accessItem});
});
return authorizationClone;
return accessItemClone;
}
private ngOnDestroy(): void {

View File

@ -1,86 +1,102 @@
<taskana-spinner [isRunning]="requestInProgress" [isModal]= "modalSpinner" class = "centered-horizontally floating"></taskana-spinner>
<taskana-general-message-modal *ngIf="modalErrorMessage" [message]="modalErrorMessage" [title]="modalTitle" error = "true" ></taskana-general-message-modal>
<div id = "wb-information" class="panel panel-default">
<taskana-spinner [isRunning]="requestInProgress" [isModal]="modalSpinner" class="centered-horizontally floating"></taskana-spinner>
<taskana-general-message-modal *ngIf="modalErrorMessage" [message]="modalErrorMessage" [title]="modalTitle" error="true"></taskana-general-message-modal>
<div id="wb-information" class="panel panel-default">
<div class="panel-heading">
<div class="btn-group pull-right">
<button type="button" (click)="onSave()" class="btn btn-default btn-primary">Save</button>
<button type="button" [disabled]="!WorkbasketForm.form.valid" (click)="onSave()" class="btn btn-default btn-primary">Save</button>
<button type="button" (click)="onClear()" class="btn btn-default">Undo changes</button>
</div>
<h4 class="panel-header">{{workbasket.name}}</h4>
</div>
<div class="panel-body">
<form class="col-md-6">
<form #WorkbasketForm="ngForm">
<div class="col-md-6">
<div class="form-group required">
<label for="wb-key" class="control-label">Key</label>
<input type="text" class="form-control" id="wb-key" placeholder="key" [(ngModel)]="workbasket.key" name ="workbasket.key">
<input type="text" required #key="ngModel" class="form-control" id="wb-key" placeholder="Key" [(ngModel)]="workbasket.key"
name="workbasket.key">
<div [hidden]="key.valid" class="required-text">
* Key is required
</div>
</div>
<div class="form-group required">
<label for="wb-name" class="control-label">Name</label>
<input type="text" class="form-control" id="wb-name" placeholder="Name" [(ngModel)]="workbasket.name" name ="workbasket.name">
<input type="text" required #name="ngModel" class="form-control" id="wb-name" placeholder="Name" [(ngModel)]="workbasket.name"
name="workbasket.name">
<div [hidden]="name.valid" class="required-text">
* Name is required
</div>
</div>
<div class="form-group required">
<label for="wb-owner" class="control-label">Owner</label>
<input type="text" required #owner="ngModel" class="form-control" id="wb-owner" placeholder="Owner" [(ngModel)]="workbasket.owner"
name="workbasket.owner">
<div [hidden]="owner.valid" class="required-text">
* Owner is required
</div>
</div>
<div class="form-group">
<label for="wb-type" class="control-label">Type</label>
<div class="dropdown clearfix btn-group">
<button class="btn btn-default" type="button" id="dropdownMenu24" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
<taskana-icon-type class="vertical-align" [type] ='workbasket.type'></taskana-icon-type>
<taskana-icon-type class="vertical-align" [type]='workbasket.type'></taskana-icon-type>
{{allTypes.get(workbasket.type)}}
<span class="caret"></span>
</button>
<ul class="dropdown-menu dropdown-menu" aria-labelledby="dropdownMenu1">
<li>
<a *ngFor="let type of allTypes | mapValues | removeEmptyType" (click)="selectType(type.key)">
<taskana-icon-type class="vertical-align" [type] ='type.key'></taskana-icon-type>
<taskana-icon-type class="vertical-align" [type]='type.key'></taskana-icon-type>
{{type.value}}
</a>
</li>
</ul>
</div>
</div>
<div class="form-group required">
<label for="wb-owner" class="control-label">Owner</label>
<input type="text" class="form-control" id="wb-owner" placeholder="Owner" [(ngModel)]="workbasket.owner" name ="workbasket.owner">
</div>
<div class="form-group">
<label for="wb-domain" class="control-label">Domain</label>
<input type="text" class="form-control" id="wb-domain" placeholder="Domain" [(ngModel)]="workbasket.domain" name ="workbasket.domain" disabled="">
<input type="text" class="form-control" id="wb-domain" placeholder="Domain" [(ngModel)]="workbasket.domain" name="workbasket.domain"
disabled="">
</div>
<div class="form-group">
<label for="wb-description" class="control-label">Description</label>
<textarea class="form-control" rows="5" id="wb-description" placeholder="Description" [(ngModel)]="workbasket.description" name ="workbasket.description"></textarea>
<textarea class="form-control" rows="5" id="wb-description" placeholder="Description" [(ngModel)]="workbasket.description"
name="workbasket.description"></textarea>
</div>
</form>
<form class="col-md-6">
</div>
<div class="col-md-6">
<div class="form-group">
<label for="wb-org-level-1" class="control-label">OrgLevel 1</label>
<input type="text" class="form-control" id="wb-org-level-1" placeholder="OrgLevel 1" [(ngModel)]="workbasket.orgLevel1" name ="workbasket.orgLevel1">
<input type="text" class="form-control" id="wb-org-level-1" placeholder="OrgLevel 1" [(ngModel)]="workbasket.orgLevel1" name="workbasket.orgLevel1">
</div>
<div class="form-group">
<label for="wb-org-level-2" class="control-label">OrgLevel 2</label>
<input type="text" class="form-control" id="wb-org-level-2" placeholder="OrgLevel 2" [(ngModel)]="workbasket.orgLevel2" name ="workbasket.orgLevel2">
<input type="text" class="form-control" id="wb-org-level-2" placeholder="OrgLevel 2" [(ngModel)]="workbasket.orgLevel2" name="workbasket.orgLevel2">
</div>
<div class="form-group">
<label for="wb-org-level-3" class="control-label">OrgLevel 3</label>
<input type="text" class="form-control" id="wb-org-level-3" placeholder="OrgLevel 3" [(ngModel)]="workbasket.orgLevel3" name ="workbasket.orgLevel3">
<input type="text" class="form-control" id="wb-org-level-3" placeholder="OrgLevel 3" [(ngModel)]="workbasket.orgLevel3" name="workbasket.orgLevel3">
</div>
<div class="form-group">
<label for="wb-org-level-4" class="control-label">OrgLevel 4</label>
<input type="text" class="form-control" id="wb-org-level-4" placeholder="OrgLevel 4" [(ngModel)]="workbasket.orgLevel4" name ="workbasket.orgLevel4">
<input type="text" class="form-control" id="wb-org-level-4" placeholder="OrgLevel 4" [(ngModel)]="workbasket.orgLevel4" name="workbasket.orgLevel4">
</div>
<div class="form-group">
<label for="wb-custom-1" class="control-label">Custom 1</label>
<input type="text" class="form-control" id="wb-custom-1" placeholder="Custom 1" [(ngModel)]="workbasket.custom1" name ="workbasket.custom1">
<input type="text" class="form-control" id="wb-custom-1" placeholder="Custom 1" [(ngModel)]="workbasket.custom1" name="workbasket.custom1">
</div>
<div class="form-group">
<label for="wb-custom-2" class="control-label">Custom 2</label>
<input type="text" class="form-control" id="wb-custom-2" placeholder="Custom 2" [(ngModel)]="workbasket.custom2" name ="workbasket.custom2">
<input type="text" class="form-control" id="wb-custom-2" placeholder="Custom 2" [(ngModel)]="workbasket.custom2" name="workbasket.custom2">
</div>
<div class="form-group">
<label for="wb-custom-3" class="control-label">Custom 3</label>
<input type="text" class="form-control" id="wb-custom-3" placeholder="Custom 3" [(ngModel)]="workbasket.custom3" name ="workbasket.custom3">
<input type="text" class="form-control" id="wb-custom-3" placeholder="Custom 3" [(ngModel)]="workbasket.custom3" name="workbasket.custom3">
</div>
<div class="form-group">
<label for="wb-custom-4" class="control-label">Custom 4</label>
<input type="text" class="form-control" id="wb-custom-4" placeholder="Custom 4" [(ngModel)]="workbasket.custom4" name ="workbasket.custom4">
<input type="text" class="form-control" id="wb-custom-4" placeholder="Custom 4" [(ngModel)]="workbasket.custom4" name="workbasket.custom4">
</div>
</div>
</form>
</div>

View File

@ -48,9 +48,9 @@ describe('InformationComponent', () => {
fixture.detectChanges();
expect(debugElement.querySelector('#wb-information')).toBeDefined();
expect(debugElement.querySelector('#wb-information > .panel-heading > h4').textContent).toBe('name');
expect(debugElement.querySelectorAll('#wb-information > .panel-body > form').length).toBe(2);
expect(debugElement.querySelectorAll('#wb-information > .panel-body > form').length).toBe(1);
fixture.whenStable().then(() => {
expect(debugElement.querySelector('#wb-information > .panel-body > form:first-child > div:first-child > input').value).toBe('keyModified');
expect(debugElement.querySelector('#wb-information > .panel-body > form > div > div > input ').value).toBe('keyModified');
});
}));

View File

@ -47,6 +47,10 @@ export class WorkbasketInformationComponent implements OnInit {
this.workbasket.type = type;
}
onSubmit(){
debugger;
}
onSave() {
this.beforeRequest();
@ -74,6 +78,7 @@ export class WorkbasketInformationComponent implements OnInit {
this.modalSpinner = true;
this.modalErrorMessage = undefined;
}
private afterRequest(){
this.requestInProgress = false;
this.workbasketService.triggerWorkBasketSaved();

View File

@ -0,0 +1,11 @@
.ng-invalid:not(form) {
border-color: #a94442;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
}
.required-text {
padding-left: 15px;
color: #a94442;
}

View File

@ -250,3 +250,7 @@ li > div.row > dl {
.vertical-align{
vertical-align: middle;
}
.panel-heading{
min-height: 60px;
}