TSK-196 Add accessItems saving feature.

This commit is contained in:
Martin Rojas Miguel Angel 2018-03-02 13:53:31 +01:00 committed by Holger Hagen
parent e984773b02
commit a7885a0830
17 changed files with 264 additions and 321 deletions

View File

@ -24,7 +24,7 @@ import { CategoriesadministrationComponent } from './categoriesadministration/ca
import { WorkbasketDistributiontargetsComponent } from './workbasket-distributiontargets/workbasket-distributiontargets.component'; import { WorkbasketDistributiontargetsComponent } from './workbasket-distributiontargets/workbasket-distributiontargets.component';
import { WorkbasketDetailsComponent } from './workbasket/details/workbasket-details.component'; import { WorkbasketDetailsComponent } from './workbasket/details/workbasket-details.component';
import { WorkbasketInformationComponent } from './workbasket/details/information/workbasket-information.component'; import { WorkbasketInformationComponent } from './workbasket/details/information/workbasket-information.component';
import { AuthorizationsComponent } from './workbasket/details/authorizations/authorizations.component'; import { AccessItemsComponent } from './workbasket/details/access-items/access-items.component';
import { NoAccessComponent } from './workbasket/noAccess/no-access.component'; import { NoAccessComponent } from './workbasket/noAccess/no-access.component';
import { SpinnerComponent } from './shared/spinner/spinner.component'; import { SpinnerComponent } from './shared/spinner/spinner.component';
import { FilterComponent } from './shared/filter/filter.component'; import { FilterComponent } from './shared/filter/filter.component';
@ -70,7 +70,7 @@ const DECLARATIONS = [
CategoriestreeComponent, CategoriestreeComponent,
CategoryeditorComponent, CategoryeditorComponent,
CategoriesadministrationComponent, CategoriesadministrationComponent,
AuthorizationsComponent, AccessItemsComponent,
WorkbasketDetailsComponent, WorkbasketDetailsComponent,
WorkbasketDistributiontargetsComponent, WorkbasketDistributiontargetsComponent,
MasterAndDetailComponent, MasterAndDetailComponent,

View File

@ -1,6 +1,6 @@
import { Links } from "./links"; import { Links } from "./links";
export class WorkbasketAuthorization { export class WorkbasketAccessItems {
constructor( constructor(
public accessItemId: string = '', public accessItemId: string = '',
public workbasketId: string = '', public workbasketId: string = '',

View File

@ -2,7 +2,7 @@ import { Injectable } from '@angular/core';
import { HttpClientModule, HttpClient, HttpHeaders, HttpResponse, HttpErrorResponse } from '@angular/common/http'; import { HttpClientModule, HttpClient, HttpHeaders, HttpResponse, HttpErrorResponse } from '@angular/common/http';
import { WorkbasketSummary } from '../model/workbasketSummary'; import { WorkbasketSummary } from '../model/workbasketSummary';
import { Workbasket } from '../model/workbasket'; import { Workbasket } from '../model/workbasket';
import { WorkbasketAuthorization } from '../model/workbasket-authorization'; import { WorkbasketAccessItems } from '../model/workbasket-access-items';
import { environment } from '../../environments/environment'; import { environment } from '../../environments/environment';
import { Observable } from 'rxjs/Observable'; import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject'; import { Subject } from 'rxjs/Subject';
@ -51,7 +51,7 @@ export class WorkbasketService {
//#region "REST calls" //#region "REST calls"
// GET // GET
getWorkBasketsSummary( forceRequest: boolean = false, getWorkBasketsSummary(forceRequest: boolean = false,
sortBy: string = this.KEY, sortBy: string = this.KEY,
order: string = Direction.ASC, order: string = Direction.ASC,
name: string = undefined, name: string = undefined,
@ -63,22 +63,17 @@ export class WorkbasketService {
key: string = undefined, key: string = undefined,
keyLike: string = undefined, keyLike: string = undefined,
requiredPermission: string = undefined): Observable<WorkbasketSummary[]> { requiredPermission: string = undefined): Observable<WorkbasketSummary[]> {
if(this.workbasketSummaryRef && !forceRequest){ if (this.workbasketSummaryRef && !forceRequest) {
return this.workbasketSummaryRef; return this.workbasketSummaryRef;
} }
return this.httpClient.get<WorkbasketSummary[]>(`${environment.taskanaRestUrl}/v1/workbaskets/${this.getWorkbasketSummaryQueryParameters(sortBy, order, name, return this.httpClient.get<WorkbasketSummary[]>(`${environment.taskanaRestUrl}/v1/workbaskets/${this.getWorkbasketSummaryQueryParameters(sortBy, order, name,
nameLike, descLike, owner, ownerLike, type, key, keyLike, requiredPermission)}`, this.httpOptions); nameLike, descLike, owner, ownerLike, type, key, keyLike, requiredPermission)}`, this.httpOptions);
} }
// GET // GET
getWorkBasket(url: string): Observable<Workbasket> { getWorkBasket(url: string): Observable<Workbasket> {
return this.httpClient.get<Workbasket>(url, this.httpOptions); return this.httpClient.get<Workbasket>(url, this.httpOptions);
} }
getWorkBasket1(id: string): Observable<Workbasket> {
return this.httpClient.get<Workbasket>(environment.taskanaRestUrl + '/v1/workbaskets/' + id, this.httpOptions);
}
// POST // POST
createWorkbasket(url: string, workbasket: Workbasket): Observable<Workbasket> { createWorkbasket(url: string, workbasket: Workbasket): Observable<Workbasket> {
return this.httpClient return this.httpClient
@ -95,22 +90,19 @@ export class WorkbasketService {
return this.httpClient.delete(environment.taskanaRestUrl + '/v1/workbaskets/' + id, this.httpOptions); return this.httpClient.delete(environment.taskanaRestUrl + '/v1/workbaskets/' + id, this.httpOptions);
} }
// GET // GET
getWorkBasketAuthorizations(id: String): Observable<WorkbasketAuthorization[]> { getWorkBasketAccessItems(id: String): Observable<WorkbasketAccessItems[]> {
return this.httpClient.get<WorkbasketAuthorization[]>(environment.taskanaRestUrl + '/v1/workbaskets/' + id + '/authorizations', this.httpOptions); return this.httpClient.get<WorkbasketAccessItems[]>(environment.taskanaRestUrl + '/v1/workbaskets/' + id + '/workbasketAccessItems', this.httpOptions);
} }
// POST // POST
createWorkBasketAuthorization(workbasketAuthorization: WorkbasketAuthorization): Observable<WorkbasketAuthorization> { createWorkBasketAccessItem(workbasketAccessItem: WorkbasketAccessItems): Observable<WorkbasketAccessItems> {
return this.httpClient.post<WorkbasketAuthorization>(environment.taskanaRestUrl + '/v1/workbaskets/authorizations', workbasketAuthorization, this.httpOptions); return this.httpClient.post<WorkbasketAccessItems>(environment.taskanaRestUrl + '/v1/workbaskets/workbasketAccessItems', workbasketAccessItem, this.httpOptions);
} }
// PUT // PUT
updateWorkBasketAuthorization(workbasketAuthorization: WorkbasketAuthorization): Observable<WorkbasketAuthorization> { updateWorkBasketAccessItem(url: string, workbasketAccessItem: Array<WorkbasketAccessItems>): Observable<string> {
return this.httpClient.put<WorkbasketAuthorization>(environment.taskanaRestUrl + '/v1/workbaskets/authorizations/' + workbasketAuthorization.accessId, workbasketAuthorization, this.httpOptions) return this.httpClient.put<string>(url,
workbasketAccessItem,
this.httpOptions);
} }
// DELETE
deleteWorkBasketAuthorization(workbasketAuthorization: WorkbasketAuthorization) {
return this.httpClient.delete(environment.taskanaRestUrl + '/v1/workbaskets/authorizations/' + workbasketAuthorization.accessId, this.httpOptions);
}
//#endregion //#endregion
//#region "Service extras" //#region "Service extras"
@ -162,7 +154,7 @@ export class WorkbasketService {
return query; return query;
} }
private handleError (error: Response | any) { private handleError(error: Response | any) {
// In a real world app, you might use a remote logging infrastructure // In a real world app, you might use a remote logging infrastructure
let errMsg: string; let errMsg: string;
if (error instanceof Response) { if (error instanceof Response) {

View File

@ -1,6 +1,6 @@
.footer{ .footer{
position: fixed; position: absolute;
bottom: 0; bottom: 0;
width: 100%; width: 100%;
margin-bottom: 0px; margin-bottom: 0px;

View File

@ -1,6 +1,6 @@
<div class="modal fade" #generalModal tabindex="-1" data-backdrop="static" data-keyboard="false" role="dialog" aria-labelledby="generalModalLabel"> <div class="modal fade" #generalModal tabindex="-1" data-backdrop="static" data-keyboard="false" role="dialog" aria-labelledby="generalModalLabel">
<div class="modal-dialog" role="document"> <div class="modal-dialog" role="document">
<div class="modal-content"> <div class="modal-content word-break">
<div class="modal-header"> <div class="modal-header">
<h4 class="modal-title" id="generalModalLabel">{{title}}</h4> <h4 class="modal-title" id="generalModalLabel">{{title}}</h4>
</div> </div>

View File

@ -0,0 +1 @@
.word-break{word-break: break-all; }

View File

@ -4,4 +4,8 @@ export class Utils {
static getSelfRef(links: Array<Links>) { static getSelfRef(links: Array<Links>) {
return links.find(l => l.rel === 'self'); return links.find(l => l.rel === 'self');
} }
static getTagLinkRef(links: Array<Links>, tag: string) {
return links.find(l => l.rel === tag );
}
} }

View File

@ -0,0 +1,110 @@
<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 *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)="clear()" class="btn btn-default">Undo changes</button>
</div>
<h4 class="panel-header">{{workbasket.name}}</h4>
</div>
<div class="panel-body">
<table class="table table-striped table-center">
<thead>
<tr>
<th></th>
<th class="text-align required-header">AccessID</th>
<th>Read</th>
<th>Open</th>
<th>Append</th>
<th>Transfer</th>
<th>Distribute</th>
<th>Custom1</th>
<th>Custom2</th>
<th>Custom3</th>
<th>Custom4</th>
<th>Custom5</th>
<th>Custom6</th>
<th>Custom7</th>
<th>Custom8</th>
<th>Custom9</th>
<th>Custom10</th>
<th>Custom11</th>
<th>Custom12</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let authorization of accessItems; let index = index;">
<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>
</td>
<td [ngClass]="{'has-changes': (accessItemsClone[index].permRead !== authorization.permRead)}">
<input type="checkbox" disabled="disabled" [(ngModel)]="authorization.permRead">
</td>
<td [ngClass]="{'has-changes': (accessItemsClone[index].permOpen !== authorization.permOpen)}">
<input type="checkbox" [(ngModel)]="authorization.permOpen">
</td>
<td [ngClass]="{'has-changes': (accessItemsClone[index].permAppend !== authorization.permAppend)}">
<input type="checkbox" [(ngModel)]="authorization.permAppend">
</td>
<td [ngClass]="{'has-changes': (accessItemsClone[index].permTransfer !== authorization.permTransfer)}">
<input type="checkbox" [(ngModel)]="authorization.permTransfer">
</td>
<td [ngClass]="{'has-changes': (accessItemsClone[index].permDistribute !== authorization.permDistribute)}">
<input type="checkbox" [(ngModel)]="authorization.permDistribute">
</td>
<td [ngClass]="{'has-changes': (accessItemsClone[index].permCustom1 !== authorization.permCustom1)}">
<input type="checkbox" [(ngModel)]="authorization.permCustom1">
</td>
<td [ngClass]="{'has-changes': (accessItemsClone[index].permCustom2 !== authorization.permCustom2)}">
<input type="checkbox" [(ngModel)]="authorization.permCustom2">
</td>
<td [ngClass]="{'has-changes': (accessItemsClone[index].permCustom3 !== authorization.permCustom3)}">
<input type="checkbox" [(ngModel)]="authorization.permCustom3">
</td>
<td [ngClass]="{'has-changes': (accessItemsClone[index].permCustom4 !== authorization.permCustom4)}">
<input type="checkbox" [(ngModel)]="authorization.permCustom4">
</td>
<td [ngClass]="{'has-changes': (accessItemsClone[index].permCustom5 !== authorization.permCustom5)}">
<input type="checkbox" [(ngModel)]="authorization.permCustom5">
</td>
<td [ngClass]="{'has-changes': (accessItemsClone[index].permCustom6 !== authorization.permCustom6)}">
<input type="checkbox" [(ngModel)]="authorization.permCustom6">
</td>
<td [ngClass]="{'has-changes': (accessItemsClone[index].permCustom7 !== authorization.permCustom7)}">
<input type="checkbox" [(ngModel)]="authorization.permCustom7">
</td>
<td [ngClass]="{'has-changes': (accessItemsClone[index].permCustom8 !== authorization.permCustom8)}">
<input type="checkbox" [(ngModel)]="authorization.permCustom8">
</td>
<td [ngClass]="{'has-changes': (accessItemsClone[index].permCustom9 !== authorization.permCustom9)}">
<input type="checkbox" [(ngModel)]="authorization.permCustom9">
</td>
<td [ngClass]="{'has-changes': (accessItemsClone[index].permCustom10 !== authorization.permCustom10)}">
<input type="checkbox" [(ngModel)]="authorization.permCustom10">
</td>
<td [ngClass]="{'has-changes': (accessItemsClone[index].permCustom11 !== authorization.permCustom11)}">
<input type="checkbox" [(ngModel)]="authorization.permCustom11">
</td>
<td [ngClass]="{'has-changes': (accessItemsClone[index].permCustom12 !== authorization.permCustom12)}">
<input type="checkbox" [(ngModel)]="authorization.permCustom12">
</td>
</tr>
</tbody>
</table>
<button type="button" (click)="addAccessItem()" class="btn btn-default">
<span><svg-icon class="green small" src="./assets/icons/wb-add.svg"></svg-icon></span>
Add new access
</button>
</div>
</div>

View File

@ -7,6 +7,10 @@ td > input[type="checkbox"] {
.text-width{ .text-width{
min-width: 150px; min-width: 150px;
} }
.required-header:after {
content:" *";
color: red;
}
td { td {
&.has-changes { &.has-changes {

View File

@ -10,17 +10,17 @@ import { AlertService } from '../../../services/alert.service';
import { GeneralMessageModalComponent } from '../../../shared/general-message-modal/general-message-modal.component'; import { GeneralMessageModalComponent } from '../../../shared/general-message-modal/general-message-modal.component';
import { Links } from '../../../model/links'; import { Links } from '../../../model/links';
import { Observable } from 'rxjs/Observable'; import { Observable } from 'rxjs/Observable';
import { AuthorizationsComponent } from './authorizations.component'; import { AccessItemsComponent } from './access-items.component';
import { WorkbasketAuthorization } from '../../../model/workbasket-authorization'; import { WorkbasketAccessItems } from '../../../model/workbasket-access-items';
describe('AuthorizationsComponent', () => { describe('AccessItemsComponent', () => {
let component: AuthorizationsComponent; let component: AccessItemsComponent;
let fixture: ComponentFixture<AuthorizationsComponent>; let fixture: ComponentFixture<AccessItemsComponent>;
let workbasketService; let workbasketService;
beforeEach(async(() => { beforeEach(async(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
declarations: [SpinnerComponent, AuthorizationsComponent, GeneralMessageModalComponent], declarations: [SpinnerComponent, AccessItemsComponent, GeneralMessageModalComponent],
imports: [FormsModule, AngularSvgIconModule, HttpClientModule, HttpModule], imports: [FormsModule, AngularSvgIconModule, HttpClientModule, HttpModule],
providers: [WorkbasketService, AlertService] providers: [WorkbasketService, AlertService]
@ -29,11 +29,11 @@ describe('AuthorizationsComponent', () => {
})); }));
beforeEach(() => { beforeEach(() => {
fixture = TestBed.createComponent(AuthorizationsComponent); fixture = TestBed.createComponent(AccessItemsComponent);
component = fixture.componentInstance; component = fixture.componentInstance;
component.workbasket = new Workbasket('1') component.workbasket = new Workbasket('1')
workbasketService = TestBed.get(WorkbasketService); workbasketService = TestBed.get(WorkbasketService);
spyOn(workbasketService, 'getWorkBasketAuthorizations').and.returnValue(Observable.of(new Array<WorkbasketAuthorization>(new WorkbasketAuthorization()))); spyOn(workbasketService, 'getWorkBasketAccessItems').and.returnValue(Observable.of(new Array<WorkbasketAccessItems>(new WorkbasketAccessItems())));
fixture.detectChanges(); fixture.detectChanges();
}); });

View File

@ -0,0 +1,97 @@
import { Component, OnInit, Input, AfterViewInit } from '@angular/core';
import { Subscription } from 'rxjs';
import { Utils } from '../../../shared/utils/utils';
import { Workbasket } from '../../../model/workbasket';
import { WorkbasketAccessItems } from '../../../model/workbasket-access-items';
import { WorkbasketService } from '../../../services/workbasket.service';
import { AlertService, AlertModel, AlertType } from '../../../services/alert.service';
declare var $: any;
@Component({
selector: 'taskana-workbasket-access-items',
templateUrl: './access-items.component.html',
styleUrls: ['./access-items.component.scss']
})
export class AccessItemsComponent implements OnInit {
@Input()
workbasket: Workbasket;
accessItems: Array<WorkbasketAccessItems>;
accessItemsClone: Array<WorkbasketAccessItems>;
accessItemsResetClone: Array<WorkbasketAccessItems>;
requestInProgress: boolean = false;
modalSpinner: boolean = true;
modalTitle: string;
modalErrorMessage: string;
accessItemsubscription: Subscription;
constructor(private workbasketService: WorkbasketService, private alertService: AlertService) { }
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);
})
}
addAccessItem() {
this.accessItems.push(new WorkbasketAccessItems(undefined,this.workbasket.workbasketId, undefined, true));
this.accessItemsClone.push(new WorkbasketAccessItems());
}
clear() {
this.accessItems = this.cloneaccessItems(this.accessItemsResetClone);
this.accessItemsClone = this.cloneaccessItems(this.accessItemsResetClone);
}
remove(index: number) {
this.accessItems.splice(index,1);
this.accessItemsClone.splice(index,1);
}
onSave() {
if(this.validateAccessItems()){
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`))
},
error => {
this.modalErrorMessage = error.message;
})
}
private validateAccessItems(): boolean {
return this.accessItems.some(element => {
if(!element.accessId || element.accessId === '') {
this.showValidationError();
return true;
}
});
}
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});
});
return authorizationClone;
}
private ngOnDestroy(): void {
if (this.accessItemsubscription) { this.accessItemsubscription.unsubscribe(); }
}
}

View File

@ -1,171 +0,0 @@
<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 *ngIf="workbasket" id="wb-information" class="panel panel-default">
<div class="panel-heading">
<div class="btn-group pull-right">
<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 class="table table-striped table-center">
<thead>
<tr>
<th></th>
<th class="text-align">AccessID</th>
<th>Read</th>
<th>Open</th>
<th>Append</th>
<th>Transfer</th>
<th>Distribute</th>
<th>Custom1</th>
<th>Custom2</th>
<th>Custom3</th>
<th>Custom4</th>
<th>Custom5</th>
<th>Custom6</th>
<th>Custom7</th>
<th>Custom8</th>
<th>Custom9</th>
<th>Custom10</th>
<th>Custom11</th>
<th>Custom12</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<span class="input-group-btn">
<button type="button" (click)="addAuthorization()" class="btn btn-default">
<svg-icon class="green small" src="./assets/icons/wb-add.svg"></svg-icon>
</button>
</span>
</td>
<td class="text-align">
<div class="input-group">
<input type="text" class="form-control" id="au-add-work-basket" [(ngModel)]="newAuthorization.accessId" placeholder="Add authorization">
</div>
</td>
<td>
<input type="checkbox" [(ngModel)]="newAuthorization.permRead">
</td>
<td>
<input type="checkbox" [(ngModel)]="newAuthorization.permOpen">
</td>
<td>
<input type="checkbox" [(ngModel)]="newAuthorization.permAppend">
</td>
<td>
<input type="checkbox" [(ngModel)]="newAuthorization.permTransfer">
</td>
<td>
<input type="checkbox" [(ngModel)]="newAuthorization.permDistribute">
</td>
<td>
<input type="checkbox" [(ngModel)]="newAuthorization.permCustom1">
</td>
<td>
<input type="checkbox" [(ngModel)]="newAuthorization.permCustom2">
</td>
<td>
<input type="checkbox" [(ngModel)]="newAuthorization.permCustom3">
</td>
<td>
<input type="checkbox" [(ngModel)]="newAuthorization.permCustom4">
</td>
<td>
<input type="checkbox" [(ngModel)]="newAuthorization.permCustom5">
</td>
<td>
<input type="checkbox" [(ngModel)]="newAuthorization.permCustom6">
</td>
<td>
<input type="checkbox" [(ngModel)]="newAuthorization.permCustom7">
</td>
<td>
<input type="checkbox" [(ngModel)]="newAuthorization.permCustom8">
</td>
<td>
<input type="checkbox" [(ngModel)]="newAuthorization.permCustom9">
</td>
<td>
<input type="checkbox" [(ngModel)]="newAuthorization.permCustom10">
</td>
<td>
<input type="checkbox" [(ngModel)]="newAuthorization.permCustom11">
</td>
<td>
<input type="checkbox" [(ngModel)]="newAuthorization.permCustom12">
</td>
</tr>
<tr *ngFor="let authorization of authorizations; let index = index;">
<td>
<button type="button" *ngIf="!authorizationState[index]" (click)="remove(index)" data-toggle="tooltip" title="Remove" class="btn btn-default remove">
<span class="glyphicon glyphicon-remove" aria-hidden="true"></span>
</button>
<button type="button" *ngIf="authorizationState[index]" (click)="save(index)" data-toggle="tooltip" title="Save" class="btn btn-default brown">
<span class="glyphicon glyphicon-floppy-remove" aria-hidden="true"></span>
</button>
</td>
<td class="text-align text-width">
<div class="input-group {{(authorizationsClone[index].accessId !== authorization.accessId)? 'has-warning': ''}}">
<input type="text" class="form-control"
(change)="checkAuthorizationState(index);" [(ngModel)]="authorization.accessId">
</div>
</td>
<td class ="{{(authorizationsClone[index].permRead !== authorization.permRead)? 'has-changes': ''}}">
<input type="checkbox" (change)="checkAuthorizationState(index)" [(ngModel)]="authorization.permRead">
</td>
<td class ="{{(authorizationsClone[index].permOpen !== authorization.permOpen)? 'has-changes': ''}}">
<input type="checkbox" (change)="checkAuthorizationState(index)" [(ngModel)]="authorization.permOpen">
</td>
<td class ="{{(authorizationsClone[index].permAppend !== authorization.permAppend)? 'has-changes': ''}}">
<input type="checkbox" (change)="checkAuthorizationState(index)" [(ngModel)]="authorization.permAppend">
</td>
<td class ="{{(authorizationsClone[index].permTransfer !== authorization.permTransfer)? 'has-changes': ''}}">
<input type="checkbox" (change)="checkAuthorizationState(index)" [(ngModel)]="authorization.permTransfer">
</td>
<td class ="{{(authorizationsClone[index].permDistribute !== authorization.permDistribute)? 'has-changes': ''}}">
<input type="checkbox" (change)="checkAuthorizationState(index)" [(ngModel)]="authorization.permDistribute">
</td>
<td class ="{{(authorizationsClone[index].permCustom1 !== authorization.permCustom1)? 'has-changes': ''}}">
<input type="checkbox" (change)="checkAuthorizationState(index)" [(ngModel)]="authorization.permCustom1">
</td>
<td class ="{{(authorizationsClone[index].permCustom2 !== authorization.permCustom2)? 'has-changes': ''}}">
<input type="checkbox" (change)="checkAuthorizationState(index)" [(ngModel)]="authorization.permCustom2">
</td>
<td class ="{{(authorizationsClone[index].permCustom3 !== authorization.permCustom3)? 'has-changes': ''}}">
<input type="checkbox" (change)="checkAuthorizationState(index)" [(ngModel)]="authorization.permCustom3">
</td>
<td class ="{{(authorizationsClone[index].permCustom4 !== authorization.permCustom4)? 'has-changes': ''}}">
<input type="checkbox" (change)="checkAuthorizationState(index)" [(ngModel)]="authorization.permCustom4">
</td>
<td class ="{{(authorizationsClone[index].permCustom5 !== authorization.permCustom5)? 'has-changes': ''}}">
<input type="checkbox" (change)="checkAuthorizationState(index)" [(ngModel)]="authorization.permCustom5">
</td>
<td class ="{{(authorizationsClone[index].permCustom6 !== authorization.permCustom6)? 'has-changes': ''}}">
<input type="checkbox" (change)="checkAuthorizationState(index)" [(ngModel)]="authorization.permCustom6">
</td>
<td class ="{{(authorizationsClone[index].permCustom7 !== authorization.permCustom7)? 'has-changes': ''}}">
<input type="checkbox" (change)="checkAuthorizationState(index)" [(ngModel)]="authorization.permCustom7">
</td>
<td class ="{{(authorizationsClone[index].permCustom8 !== authorization.permCustom8)? 'has-changes': ''}}">
<input type="checkbox" (change)="checkAuthorizationState(index)" [(ngModel)]="authorization.permCustom8">
</td>
<td class ="{{(authorizationsClone[index].permCustom9 !== authorization.permCustom9)? 'has-changes': ''}}">
<input type="checkbox" (change)="checkAuthorizationState(index)" [(ngModel)]="authorization.permCustom9">
</td>
<td class ="{{(authorizationsClone[index].permCustom10 !== authorization.permCustom10)? 'has-changes': ''}}">
<input type="checkbox" (change)="checkAuthorizationState(index)" [(ngModel)]="authorization.permCustom10">
</td>
<td class ="{{(authorizationsClone[index].permCustom11 !== authorization.permCustom11)? 'has-changes': ''}}">
<input type="checkbox" (change)="checkAuthorizationState(index)" [(ngModel)]="authorization.permCustom11">
</td>
<td class ="{{(authorizationsClone[index].permCustom12 !== authorization.permCustom12)? 'has-changes': ''}}">
<input type="checkbox" (change)="checkAuthorizationState(index)" [(ngModel)]="authorization.permCustom12">
</td>
</tr>
</tbody>
</table>
</div>
</div>

View File

@ -1,91 +0,0 @@
import { Component, OnInit, Input } from '@angular/core';
import { Subscription } from 'rxjs';
import { Workbasket } from '../../../model/workbasket';
import { WorkbasketAuthorization } from '../../../model/workbasket-authorization';
import { WorkbasketService } from '../../../services/workbasket.service';
@Component({
selector: 'taskana-workbasket-authorizations',
templateUrl: './authorizations.component.html',
styleUrls: ['./authorizations.component.scss']
})
export class AuthorizationsComponent implements OnInit {
@Input()
workbasket: Workbasket;
authorizations: Array<WorkbasketAuthorization>;
authorizationsClone: Array<WorkbasketAuthorization>;
authorizationsResetClone: Array<WorkbasketAuthorization>;
newAuthorization: WorkbasketAuthorization = new WorkbasketAuthorization();
authorizationState: Array<boolean>;
requestInProgress: boolean = false;
modalSpinner: boolean = true;
modalTitle: string;
modalErrorMessage: string;
authorizationSubscription: Subscription;
constructor(private workbasketService: WorkbasketService) { }
ngOnInit() {
this.authorizationSubscription = this.workbasketService.getWorkBasketAuthorizations(this.workbasket.workbasketId).subscribe( (authorizations: Array<WorkbasketAuthorization>) =>{
this.authorizations = authorizations;
this.authorizationsClone = this.cloneAuthorizations(this.authorizations);
this.authorizationsResetClone = this.cloneAuthorizations(this.authorizations);
})
}
addAuthorization(){
this.authorizations.push({...this.newAuthorization});
this.authorizationsClone.push({...this.newAuthorization});
this.authorizationState.push(false);
this.newAuthorization = new WorkbasketAuthorization();
}
authorizationToggle(index: number) {
this.checkAuthorizationState(index);
}
clear() {
this.authorizations = this.cloneAuthorizations(this.authorizationsResetClone);
this.authorizationsClone = this.cloneAuthorizations(this.authorizationsResetClone);
}
remove(index: number) {
this.authorizations.splice(index,1);
this.authorizationsClone.splice(index,1);
}
save(index: number) {
}
private resetAuthorizationsState() {
this.authorizationState = new Array<boolean>(this.authorizations.length);
}
private checkAuthorizationState(index: number) {
this.authorizationState[index] = false;
Object.keys(this.authorizations[index]).forEach(key =>{
if(this.authorizations[index][key]!== this.authorizationsClone[index][key]){
this.authorizationState[index] = true;
return;
}
});
}
private cloneAuthorizations(inputAuthorization): Array<WorkbasketAuthorization>{
let authorizationClone = new Array<WorkbasketAuthorization>();
inputAuthorization.forEach(authorization => {
authorizationClone.push({... authorization});
});
this.resetAuthorizationsState();
return authorizationClone;
}
private ngOnDestroy(): void {
if (this.authorizationSubscription) { this.authorizationSubscription.unsubscribe(); }
}
}

View File

@ -10,7 +10,7 @@
<a href="#work-baskets" aria-controls="work baskets" role="tab" data-toggle="tab" aria-expanded="true">Information</a> <a href="#work-baskets" aria-controls="work baskets" role="tab" data-toggle="tab" aria-expanded="true">Information</a>
</li> </li>
<li role="presentation" class="inactive"> <li role="presentation" class="inactive">
<a href="#authorizations" aria-controls="Authorizations" role="tab" data-toggle="tab" aria-expanded="true">Authorizations</a> <a href="#access-items" aria-controls="Acccess" role="tab" data-toggle="tab" aria-expanded="true">Access</a>
</li> </li>
<li role="presentation" class="inactive"> <li role="presentation" class="inactive">
<a href="#distribution-targets" aria-controls="distribution targets" role="tab" data-toggle="tab" aria-expanded="true">Distribution targets</a> <a href="#distribution-targets" aria-controls="distribution targets" role="tab" data-toggle="tab" aria-expanded="true">Distribution targets</a>
@ -20,8 +20,8 @@
<div role="tabpanel" class="tab-pane active" id="work-baskets"> <div role="tabpanel" class="tab-pane active" id="work-baskets">
<workbasket-information [workbasket]="workbasket"></workbasket-information> <workbasket-information [workbasket]="workbasket"></workbasket-information>
</div> </div>
<div role="tabpanel" class="tab-pane inactive" id="authorizations"> <div role="tabpanel" class="tab-pane inactive" id="access-items">
<taskana-workbasket-authorizations [workbasket]="workbasket"></taskana-workbasket-authorizations> <taskana-workbasket-access-items [workbasket]="workbasket"></taskana-workbasket-access-items>
</div> </div>
<div role="tabpanel" class="tab-pane inactive" id="distribution-targets"> <div role="tabpanel" class="tab-pane inactive" id="distribution-targets">
<!-- <taskana-workbasket-distributiontargets [workbasket]="workbasket"></taskana-workbasket-distributiontargets>--> <!-- <taskana-workbasket-distributiontargets [workbasket]="workbasket"></taskana-workbasket-distributiontargets>-->

View File

@ -2,7 +2,7 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { WorkbasketDetailsComponent } from './workbasket-details.component'; import { WorkbasketDetailsComponent } from './workbasket-details.component';
import { NoAccessComponent } from '../noAccess/no-access.component'; import { NoAccessComponent } from '../noAccess/no-access.component';
import { WorkbasketInformationComponent } from './information/workbasket-information.component'; import { WorkbasketInformationComponent } from './information/workbasket-information.component';
import { AuthorizationsComponent } from './authorizations/authorizations.component'; import { AccessItemsComponent } from './access-items/access-items.component';
import { Workbasket } from 'app/model/workbasket'; import { Workbasket } from 'app/model/workbasket';
import { Observable } from 'rxjs/Observable'; import { Observable } from 'rxjs/Observable';
import { SpinnerComponent } from '../../shared/spinner/spinner.component'; import { SpinnerComponent } from '../../shared/spinner/spinner.component';
@ -35,7 +35,7 @@ describe('WorkbasketDetailsComponent', () => {
beforeEach(async(() => { beforeEach(async(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports:[RouterTestingModule, FormsModule, AngularSvgIconModule, HttpClientModule, HttpModule], imports:[RouterTestingModule, FormsModule, AngularSvgIconModule, HttpClientModule, HttpModule],
declarations: [ WorkbasketDetailsComponent, NoAccessComponent, WorkbasketInformationComponent, SpinnerComponent, IconTypeComponent, MapValuesPipe, RemoveNoneTypePipe, AlertComponent, GeneralMessageModalComponent, AuthorizationsComponent ], declarations: [ WorkbasketDetailsComponent, NoAccessComponent, WorkbasketInformationComponent, SpinnerComponent, IconTypeComponent, MapValuesPipe, RemoveNoneTypePipe, AlertComponent, GeneralMessageModalComponent, AccessItemsComponent ],
providers:[WorkbasketService, MasterAndDetailService, PermissionService, AlertService] providers:[WorkbasketService, MasterAndDetailService, PermissionService, AlertService]
}) })
.compileComponents(); .compileComponents();

View File

@ -190,10 +190,6 @@ li > div.row > dl {
text-align: left; text-align: left;
} }
.table-center > tbody >tr:first-child >td {
border-bottom: 2px solid #ddd;
}
.btn.remove { .btn.remove {
color: crimson; color: crimson;
} }

View File

@ -14,4 +14,5 @@
<app-root></app-root> <app-root></app-root>
</body> </body>
</html> </html>