TSK-199 Create distribution targets view
This commit is contained in:
parent
5e648b7eb7
commit
2bd7acd656
|
@ -21,9 +21,9 @@ import { CategorieslistComponent } from './categorieslist/categorieslist.compone
|
|||
import { CategoriestreeComponent } from './categoriestree/categoriestree.component';
|
||||
import { CategoryeditorComponent } from './categoryeditor/categoryeditor.component';
|
||||
import { CategoriesadministrationComponent } from './categoriesadministration/categoriesadministration.component';
|
||||
import { WorkbasketDistributiontargetsComponent } from './workbasket-distributiontargets/workbasket-distributiontargets.component';
|
||||
import { WorkbasketDetailsComponent } from './workbasket/details/workbasket-details.component';
|
||||
import { WorkbasketInformationComponent } from './workbasket/details/information/workbasket-information.component';
|
||||
import { DistributionTargetsComponent } from './workbasket/details/distribution-targets/distribution-targets.component';
|
||||
import { AccessItemsComponent } from './workbasket/details/access-items/access-items.component';
|
||||
import { NoAccessComponent } from './workbasket/noAccess/no-access.component';
|
||||
import { SpinnerComponent } from './shared/spinner/spinner.component';
|
||||
|
@ -51,6 +51,7 @@ import { AlertService } from './services/alert.service';
|
|||
*/
|
||||
import { MapValuesPipe } from './pipes/map-values.pipe';
|
||||
import { RemoveNoneTypePipe } from './pipes/remove-none-type';
|
||||
import { SelectWorkBasketPipe } from './pipes/seleted-workbasket.pipe';
|
||||
|
||||
const MODULES = [
|
||||
BrowserModule,
|
||||
|
@ -74,7 +75,6 @@ const DECLARATIONS = [
|
|||
CategoriesadministrationComponent,
|
||||
AccessItemsComponent,
|
||||
WorkbasketDetailsComponent,
|
||||
WorkbasketDistributiontargetsComponent,
|
||||
MasterAndDetailComponent,
|
||||
WorkbasketInformationComponent,
|
||||
NoAccessComponent,
|
||||
|
@ -83,9 +83,11 @@ const DECLARATIONS = [
|
|||
IconTypeComponent,
|
||||
AlertComponent,
|
||||
GeneralMessageModalComponent,
|
||||
DistributionTargetsComponent,
|
||||
SortComponent,
|
||||
MapValuesPipe,
|
||||
RemoveNoneTypePipe
|
||||
RemoveNoneTypePipe,
|
||||
SelectWorkBasketPipe
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
|
||||
@Pipe({ name: 'selectWorkbaskets' })
|
||||
export class SelectWorkBasketPipe implements PipeTransform {
|
||||
transform(originArray: any, arg0: any, arg1: any): Object[] {
|
||||
let returnArray = [];
|
||||
if (!originArray) {
|
||||
return returnArray;
|
||||
}
|
||||
for (let index = originArray.length - 1; index >= 0; index--) {
|
||||
if ((arg1 && !arg0.some(elementToRemove => { return originArray[index].workbasketId === elementToRemove.workbasketId})) ||
|
||||
!arg1 && arg0.some(elementToRemove => { return originArray[index].workbasketId === elementToRemove.workbasketId})) {
|
||||
originArray.splice(index, 1);
|
||||
}
|
||||
}
|
||||
returnArray = originArray;
|
||||
return returnArray;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -96,6 +96,12 @@ export class WorkbasketService {
|
|||
workbasketAccessItem,
|
||||
this.httpOptions);
|
||||
}
|
||||
// GET
|
||||
getWorkBasketsDistributionTargets(id: String): Observable<WorkbasketSummary[]> {
|
||||
return this.httpClient.get<WorkbasketSummary[]>(environment.taskanaRestUrl + '/v1/workbaskets/' + id + '/distributiontargets', this.httpOptions);
|
||||
}
|
||||
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region "Service extras"
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
<div type="text" id="{{target}}" data-toogle="collapse" class="list-group-seach collapse">
|
||||
<div id="{{target}}" data-toogle="collapse" class="list-group-search collapse">
|
||||
<div class="row">
|
||||
<div class="dropdown col-xs-2">
|
||||
<button class="btn btn-default" type="button" id="dropdownMenufilter" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
|
||||
<button class="btn btn-default" (click)="toggleDropDown = !toggleDropDown" type="button" id="dropdownMenufilter" data-toggle="dropdown"
|
||||
aria-haspopup="true" aria-expanded="true">
|
||||
<taskana-icon-type [type]="filter.type" class="vertical-align"></taskana-icon-type>
|
||||
|
||||
</button>
|
||||
<ul class="dropdown-menu dropdown-menu-users" role="menu">
|
||||
<ul class="dropdown-menu dropdown-menu-users" [ngClass]="{'hidden': !toggleDropDown}" role="menu">
|
||||
<li *ngFor="let type of allTypes | mapValues">
|
||||
<button type="button" (click)="selectType(type.key); search()" class="btn btn-default btn-users-list" data-toggle="tooltip" [title]="type.value">
|
||||
<button type="button" (click)="selectType(type.key); toggleDropDown = !toggleDropDown; search()" class="btn btn-default btn-users-list" data-toggle="tooltip"
|
||||
[title]="type.value">
|
||||
<taskana-icon-type class="vertical-align" [type]='type.key'></taskana-icon-type>
|
||||
</button>
|
||||
</li>
|
||||
|
@ -19,25 +21,27 @@
|
|||
<div class="col-xs-4">
|
||||
<input type="text" [(ngModel)]="filter.key" (keyup.enter)="search()" class="form-control" id="wb-display-key-filter" placeholder="Filter key">
|
||||
</div>
|
||||
<button (click)="clear(); search()" type="button"
|
||||
class="btn btn-default glyphicon glyphicon-ban-circle blue pull-right margin-right" data-toggle="tooltip" title="Clear">
|
||||
<button (click)="clear(); search()" type="button" class="btn btn-default glyphicon glyphicon-ban-circle blue pull-right margin-right"
|
||||
data-toggle="tooltip" title="Clear">
|
||||
</button>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-2">
|
||||
</div>
|
||||
<div class="col-xs-8">
|
||||
<input type="text" [(ngModel)]= "filter.description" (keyup.enter)="search()" class="form-control" id="wb-display-description-filter" placeholder="Filter by description">
|
||||
<input type="text" [(ngModel)]="filter.description" (keyup.enter)="search()" class="form-control" id="wb-display-description-filter"
|
||||
placeholder="Filter by description">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-2">
|
||||
</div>
|
||||
<div class="col-xs-8">
|
||||
<input type="text" [(ngModel)]= "filter.owner" (keyup.enter)="search()" class="form-control" id="wb-display-task-owner-filter" placeholder="Filter by Task owner">
|
||||
<input type="text" [(ngModel)]="filter.owner" (keyup.enter)="search()" class="form-control" id="wb-display-task-owner-filter"
|
||||
placeholder="Filter by Task owner">
|
||||
</div>
|
||||
<button (click)="search()" type="button"
|
||||
class="btn btn-default glyphicon glyphicon-search blue pull-right margin-right" data-toggle="tooltip" title="Search">
|
||||
<button (click)="search()" type="button" class="btn btn-default glyphicon glyphicon-search blue pull-right margin-right"
|
||||
data-toggle="tooltip" title="Search">
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
|
@ -4,3 +4,12 @@
|
|||
}
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
.list-group-search {
|
||||
padding: 10px 15px;
|
||||
}
|
||||
|
||||
.btn-users-list {
|
||||
border: 0px solid transparent;
|
||||
/* this was 1px earlier */
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
<div [hidden]="!isDelayedRunning">
|
||||
<div class="sk-circle spinner-centered" [hidden]="this.isModal">
|
||||
<div class="sk-circle {{positionClass? positionClass: 'spinner-centered'}}" [hidden]="this.isModal">
|
||||
<div class="sk-circle1 sk-child"></div>
|
||||
<div class="sk-circle2 sk-child"></div>
|
||||
<div class="sk-circle3 sk-child"></div>
|
||||
|
@ -15,7 +15,7 @@
|
|||
</div>
|
||||
<div #spinnerModal class="modal fade" id="spinner-modal" data-backdrop="static" data-keyboard="false" role="dialog">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-dialog spinner-centered">
|
||||
<div class="modal-dialog {{positionClass? positionClass: 'spinner-centered'}}">
|
||||
<div class="sk-circle">
|
||||
<div class="sk-circle1 sk-child"></div>
|
||||
<div class="sk-circle2 sk-child"></div>
|
||||
|
|
|
@ -34,6 +34,10 @@ export class SpinnerComponent {
|
|||
@Input()
|
||||
isModal: boolean = false;
|
||||
|
||||
@Input()
|
||||
positionClass: string = undefined;
|
||||
|
||||
|
||||
@ViewChild('spinnerModal')
|
||||
private modal;
|
||||
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
<!-- <h2>Distribution Targets</h2>
|
||||
<div *ngFor="let alert of alerts">
|
||||
<alert [type]="alert.type" dismissible="true" [dismissOnTimeout]="5000">{{ alert.msg }}</alert>
|
||||
</div>
|
||||
<div class="col-xs-6 col-md-6">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<th>All Workbaskets</th>
|
||||
<th>Actions</th>
|
||||
</thead>
|
||||
<tr *ngFor="let workbasket of workbaskets">
|
||||
<td>{{ workbasket.name }}</td>
|
||||
<td>
|
||||
<button type="button" class="btn btn-default" aria-label="Left Align" (click)="onAdd(workbasket)">
|
||||
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span></button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="col-xs-6 col-md-6">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<th>Selected Workbaskets</th>
|
||||
<th>Actions</th>
|
||||
</thead>
|
||||
<tr *ngFor="let workbasket of workbasket.distributionTargets">
|
||||
<td>{{ resolveName(workbasket) }}</td>
|
||||
<td>
|
||||
<button type="button" class="btn btn-default" aria-label="Left Align" (click)="onDelete(workbasket)">
|
||||
<span class="glyphicon glyphicon-trash" aria-hidden="true"></span></button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div> -->
|
|
@ -1,25 +0,0 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { WorkbasketDistributiontargetsComponent } from './workbasket-distributiontargets.component';
|
||||
|
||||
describe('WorkbasketDistributiontargetsComponent', () => {
|
||||
let component: WorkbasketDistributiontargetsComponent;
|
||||
let fixture: ComponentFixture<WorkbasketDistributiontargetsComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ WorkbasketDistributiontargetsComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(WorkbasketDistributiontargetsComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
xit('should be created', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -1,106 +0,0 @@
|
|||
import { Component, OnInit, Input } from '@angular/core';
|
||||
import { WorkbasketSummary } from '../model/workbasketSummary';
|
||||
import { WorkbasketService } from '../services/workbasket.service'
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
|
||||
@Component({
|
||||
selector: 'app-workbasket-distributiontargets',
|
||||
templateUrl: './workbasket-distributiontargets.component.html',
|
||||
styleUrls: ['./workbasket-distributiontargets.component.css']
|
||||
})
|
||||
export class WorkbasketDistributiontargetsComponent implements OnInit {
|
||||
|
||||
@Input()
|
||||
workbasket: WorkbasketSummary;
|
||||
workbaskets: WorkbasketSummary[];
|
||||
public alerts: any = [];
|
||||
|
||||
constructor(private service: WorkbasketService) { }
|
||||
|
||||
ngOnInit() {
|
||||
//this.prepareData();
|
||||
}
|
||||
|
||||
// ngOnChange() {
|
||||
// this.prepareData();
|
||||
// }
|
||||
|
||||
// prepareData() {
|
||||
// this.service.getWorkBasketsSummary().subscribe(resultList => {
|
||||
// this.workbaskets = resultList;
|
||||
// });
|
||||
// }
|
||||
|
||||
// onAdd(w: WorkbasketSummary) {
|
||||
// if (this.workbasket.distributionTargets.length > 0) {
|
||||
// let found: boolean = false;
|
||||
// for (var i = 0, len = this.workbasket.distributionTargets.length; i < len; i++) {
|
||||
// if (this.workbasket.distributionTargets[i] === w.id) {
|
||||
// found = true;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (!found) {
|
||||
// this.onSaved(w, true);
|
||||
// } else {
|
||||
// this.alerts = [{
|
||||
// type: "danger",
|
||||
// msg: "This workbasket is already mapped!"
|
||||
// }];
|
||||
// }
|
||||
// } else {
|
||||
// this.onSaved(w, true);
|
||||
// }
|
||||
// }
|
||||
|
||||
// onDelete(id: string) {
|
||||
// this.onSaved(this.resolveObject(id), false);
|
||||
// }
|
||||
|
||||
// // get workbasket name
|
||||
// resolveName(id: string): any {
|
||||
// if (this.workbaskets != null) {
|
||||
// return this.workbaskets.filter(item => item.id === id)[0].name;
|
||||
// }
|
||||
// }
|
||||
|
||||
// // create an WorkbasketSummary
|
||||
// resolveObject(id: string): any {
|
||||
// if (this.workbaskets != null) {
|
||||
// return this.workbaskets.filter(item => item.id === id)[0];
|
||||
// }
|
||||
// }
|
||||
|
||||
// onSaved(w: WorkbasketSummary, isUpdate: boolean) {
|
||||
// if (w != null) {
|
||||
// // add changes
|
||||
// if (isUpdate) {
|
||||
// this.workbasket.distributionTargets.push(w.id);
|
||||
// } else {
|
||||
// let index = this.workbasket.distributionTargets.indexOf(w.id);
|
||||
// this.workbasket.distributionTargets.splice(index, 1);
|
||||
// }
|
||||
|
||||
// // try to save changes
|
||||
// this.service.updateWorkbasket(this.workbasket).subscribe(result => {
|
||||
// this.workbasket.id = result.id;
|
||||
// this.workbasket.name = result.name;
|
||||
// this.workbasket.description = result.description;
|
||||
// this.workbasket.owner = result.owner;
|
||||
// this.workbasket.distributionTargets = result.distributionTargets;
|
||||
// }, (err) => {
|
||||
// this.alerts = [{
|
||||
// type: "danger",
|
||||
// msg: "You are not authorized."
|
||||
// }];
|
||||
// // reset changes
|
||||
// if (isUpdate) {
|
||||
// this.workbasket.distributionTargets.pop();
|
||||
// } else {
|
||||
// this.workbasket.distributionTargets.push(w.id);
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
<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 *ngIf="workbasket && accessItems" id="wb-information" class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<div class="btn-group pull-right">
|
||||
<button type="button" (click)="onSave()" [disabled]="!AccessItemsForm.form.valid" class="btn btn-default btn-primary">Save</button>
|
||||
|
|
|
@ -58,6 +58,7 @@ export class AccessItemsComponent implements OnInit {
|
|||
}
|
||||
|
||||
onSave(): boolean {
|
||||
this.requestInProgress = true;
|
||||
if(!this.accessItems[0].links){
|
||||
return;
|
||||
}
|
||||
|
@ -66,6 +67,7 @@ export class AccessItemsComponent implements OnInit {
|
|||
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`));
|
||||
this.requestInProgress = false;
|
||||
return true;
|
||||
},
|
||||
error => {
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
<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">
|
||||
<div id="dual-list-Left" class="dual-list list-left col-xs-12 col-md-5-6 container">
|
||||
<div class="row">
|
||||
<div class="col-xs-2">
|
||||
<button (click)="toggleDtl = !toggleDtl; selectAll(0, toggleDtl);" class="btn btn-default selector" title="select all">
|
||||
<span aria-hidden="true" class="glyphicon blue {{toggleDtl? 'glyphicon-check': 'glyphicon-unchecked'}}"></span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-xs-8">
|
||||
<h5>Available distribution targets</h5>
|
||||
</div>
|
||||
<button class="btn btn-default pull-right collapsed" type="button" id="collapsedMenufilterWbDta" data-toggle="collapse" data-target="#wb-dta-filter-bar"
|
||||
aria-expanded="false">
|
||||
<span class="glyphicon glyphicon-filter blue"></span>
|
||||
</button>
|
||||
</div>
|
||||
<taskana-filter target="wb-dta-filter-bar" (performFilter)="performAvailableFilter($event)"></taskana-filter>
|
||||
<ul class="list-group dual-list-group">
|
||||
<taskana-spinner [isRunning]="requestInProgressLeft" [isModal]="modalSpinner" positionClass="centered-spinner" class="centered-horizontally floating"></taskana-spinner>
|
||||
<li class="list-group-item" *ngFor="let distributionTarget of distributionTargetsLeft | selectWorkbaskets: distributionTargetsSelected: 0"
|
||||
[class.selected]="distributionTarget.selected" type="text" (click)="distributionTarget.selected = !distributionTarget.selected">
|
||||
<div class="row">
|
||||
<dl class="col-xs-1">
|
||||
<dt>
|
||||
<taskana-icon-type class="vertical-align" [type]="distributionTarget.type"></taskana-icon-type>
|
||||
</dt>
|
||||
</dl>
|
||||
<dl class="col-xs-10">
|
||||
<dt>{{distributionTarget.name}} ({{distributionTarget.key}}) </dt>
|
||||
<dd>{{distributionTarget.description}}</dd>
|
||||
<dd>{{distributionTarget.owner}} </dd>
|
||||
</dl>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="hidden-xs hidden-sm col-md-1 list-arrows text-center button-margin-top">
|
||||
<button (click)="moveDistributionTargets(0)" [disabled] = "requestInProgressLeft || requestInProgressRight" class="btn btn-default move-right">
|
||||
<span class="glyphicon glyphicon-chevron-right blue"></span>
|
||||
</button>
|
||||
<button (click)="moveDistributionTargets(1)" [disabled] = "requestInProgressLeft || requestInProgressRight" class="btn btn-default move-left">
|
||||
<span class="glyphicon glyphicon-chevron-left blue"></span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="hidden visible-xs visible-sm col-xs-12 list-arrows text-center">
|
||||
<button (click)="moveDistributionTargets(0)" [disabled] = "requestInProgressLeft || requestInProgressRight" class="btn btn-default move-down">
|
||||
<span class="glyphicon glyphicon-chevron-down blue"></span>
|
||||
</button>
|
||||
<button (click)="moveDistributionTargets(1)" [disabled] = "requestInProgressLeft || requestInProgressRight" class="btn btn-default move-up">
|
||||
<span class="glyphicon glyphicon-chevron-up blue"></span>
|
||||
</button>
|
||||
</div>
|
||||
<div id="dual-list-right" class="dual-list list-right col-xs-12 col-md-5-6 container">
|
||||
<div class="row">
|
||||
<div class="col-xs-2">
|
||||
<button (click)="toggleDtr = !toggleDtr; selectAll(1, toggleDtr);" class="btn btn-default selector" title="select all">
|
||||
<span aria-hidden="true" class="glyphicon blue {{toggleDtr? 'glyphicon-check': 'glyphicon-unchecked'}}"></span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-xs-8">
|
||||
<h5>Selected distribution targets</h5>
|
||||
</div>
|
||||
<button class="btn btn-default pull-right collapsed" type="button" id="collapsedMenufilterWbDta" data-toggle="collapse" data-target="#wb-dts-filter-bar"
|
||||
aria-expanded="false">
|
||||
<span class="glyphicon glyphicon-filter blue"></span>
|
||||
</button>
|
||||
</div>
|
||||
<taskana-filter target="wb-dts-filter-bar" (performFilter)="performSelectedFilter($event)"></taskana-filter>
|
||||
<ul class="list-group dual-list-group">
|
||||
<taskana-spinner [isRunning]="requestInProgressRight" [isModal]="modalSpinner" positionClass="centered-spinner" class="centered-horizontally floating"></taskana-spinner>
|
||||
<ul class="list-group dual-list-group">
|
||||
<li class="list-group-item" *ngFor="let distributionTarget of distributionTargetsRight | selectWorkbaskets: distributionTargetsSelected: 1"
|
||||
[class.selected]="distributionTarget.selected" type="text" (click)="distributionTarget.selected = !distributionTarget.selected">
|
||||
<div class="row">
|
||||
<dl class="col-xs-1">
|
||||
<dt>
|
||||
<taskana-icon-type class="vertical-align" [type]="distributionTarget.type"></taskana-icon-type>
|
||||
</dt>
|
||||
</dl>
|
||||
<dl class="col-xs-10">
|
||||
<dt>{{distributionTarget.name}} ({{distributionTarget.key}}) </dt>
|
||||
<dd>{{distributionTarget.description}}</dd>
|
||||
<dd>{{distributionTarget.owner}} </dd>
|
||||
</dl>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,43 @@
|
|||
|
||||
.list-group {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.list-left li,
|
||||
.list-right li {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.button-margin-top {
|
||||
margin-top: 100px
|
||||
}
|
||||
|
||||
.list-arrows > button{
|
||||
margin: 10px 0px;
|
||||
}
|
||||
|
||||
.dual-list {
|
||||
min-height: 20px;
|
||||
padding: 5px;
|
||||
background-color: #f5f5f5;
|
||||
border: 1px solid #e3e3e3;
|
||||
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);
|
||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);
|
||||
& .row {
|
||||
padding: 10px 15px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 991px){
|
||||
max-height: calc(50vh - 150px);
|
||||
}
|
||||
max-height: calc(100vh - 250px);
|
||||
overflow: hidden;
|
||||
overflow-y: scroll;
|
||||
|
||||
}
|
||||
|
||||
.col-md-5-6 {
|
||||
@media (min-width: 992px){
|
||||
width: 45.82%;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { DistributionTargetsComponent } from './distribution-targets.component';
|
||||
|
||||
describe('DistributionTargetsComponent', () => {
|
||||
let component: DistributionTargetsComponent;
|
||||
let fixture: ComponentFixture<DistributionTargetsComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ DistributionTargetsComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(DistributionTargetsComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
xit('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,123 @@
|
|||
import { Component, OnInit, Input } from '@angular/core';
|
||||
import { Workbasket } from '../../../model/workbasket';
|
||||
import { WorkbasketSummary } from '../../../model/workbasketSummary';
|
||||
import { WorkbasketAccessItems } from '../../../model/workbasket-access-items';
|
||||
import { FilterModel } from '../../../shared/filter/filter.component'
|
||||
|
||||
import { WorkbasketService } from '../../../services/workbasket.service';
|
||||
import { AlertService, AlertModel, AlertType } from '../../../services/alert.service';
|
||||
|
||||
import { Subscription } from 'rxjs';
|
||||
import { element } from 'protractor';
|
||||
|
||||
@Component({
|
||||
selector: 'taskana-workbaskets-distribution-targets',
|
||||
templateUrl: './distribution-targets.component.html',
|
||||
styleUrls: ['./distribution-targets.component.scss']
|
||||
})
|
||||
export class DistributionTargetsComponent implements OnInit {
|
||||
|
||||
@Input()
|
||||
workbasket: Workbasket;
|
||||
|
||||
distributionTargetsSubscription: Subscription;
|
||||
workbasketSubscription: Subscription;
|
||||
workbasketFilterSubscription: Subscription;
|
||||
distributionTargetsLeft: Array<WorkbasketSummary>;
|
||||
distributionTargetsRight: Array<WorkbasketSummary>;
|
||||
distributionTargetsSelected: Array<WorkbasketSummary>;
|
||||
|
||||
|
||||
filterBy: FilterModel = new FilterModel();
|
||||
requestInProgress: boolean = false;
|
||||
requestInProgressLeft: boolean = false;
|
||||
requestInProgressRight: boolean = false;
|
||||
|
||||
constructor(private workbasketService: WorkbasketService) { }
|
||||
|
||||
ngOnInit() {
|
||||
this.requestInProgressLeft = true;
|
||||
this.requestInProgressRight = true;
|
||||
this.distributionTargetsSubscription = this.workbasketService.getWorkBasketsDistributionTargets(this.workbasket.workbasketId).subscribe((distributionTargetsSelected: Array<WorkbasketSummary>) => {
|
||||
this.distributionTargetsSelected = distributionTargetsSelected;
|
||||
this.workbasketSubscription = this.workbasketService.getWorkBasketsSummary().subscribe((distributionTargetsAvailable: Array<WorkbasketSummary>) => {
|
||||
this.distributionTargetsLeft = distributionTargetsAvailable;
|
||||
this.distributionTargetsRight = Object.assign([], distributionTargetsAvailable);
|
||||
this.requestInProgressLeft = false;
|
||||
this.requestInProgressRight = false;
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
selectAll(side: number, selected: boolean) {
|
||||
if (side === 0) {
|
||||
this.distributionTargetsLeft.forEach((element: any) => {
|
||||
element.selected = selected;
|
||||
});
|
||||
}
|
||||
else if (side === 1) {
|
||||
this.distributionTargetsRight.forEach((element: any) => {
|
||||
element.selected = selected;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
moveDistributionTargets(side: number) {
|
||||
if (side === 0) {
|
||||
let itemsSelected = this.getSelectedItems(this.distributionTargetsLeft, this.distributionTargetsRight)
|
||||
this.distributionTargetsSelected = this.distributionTargetsSelected.concat(itemsSelected);
|
||||
this.distributionTargetsRight = this.distributionTargetsRight.concat(itemsSelected);
|
||||
}
|
||||
else if (side === 1) {
|
||||
let itemsSelected = this.getSelectedItems(this.distributionTargetsRight, this.distributionTargetsLeft);
|
||||
this.distributionTargetsSelected = this.removeSeletedItems(this.distributionTargetsSelected, itemsSelected);
|
||||
this.distributionTargetsRight = this.removeSeletedItems(this.distributionTargetsRight, itemsSelected);
|
||||
this.distributionTargetsLeft = this.distributionTargetsLeft.concat(itemsSelected);
|
||||
}
|
||||
}
|
||||
|
||||
performAvailableFilter(filterBy: FilterModel) {
|
||||
this.filterBy = filterBy;
|
||||
this.performFilter(0);
|
||||
}
|
||||
performSelectedFilter(filterBy: FilterModel) {
|
||||
this.filterBy = filterBy;
|
||||
this.performFilter(1);
|
||||
}
|
||||
|
||||
private performFilter(listType: number) {
|
||||
|
||||
listType ? this.distributionTargetsRight = undefined : this.distributionTargetsLeft = undefined;
|
||||
listType ? this.requestInProgressRight = true : this.requestInProgressLeft = true;
|
||||
this.workbasketFilterSubscription = this.workbasketService.getWorkBasketsSummary(true, undefined, undefined, undefined,
|
||||
this.filterBy.name, this.filterBy.description, undefined, this.filterBy.owner,
|
||||
this.filterBy.type, undefined, this.filterBy.key).subscribe(resultList => {
|
||||
listType ? this.distributionTargetsRight = resultList : this.distributionTargetsLeft = resultList;
|
||||
listType ? this.requestInProgressRight = false : this.requestInProgressLeft = false;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
private getSelectedItems(originList: any, destinationList: any): Array<any> {
|
||||
return originList.filter((element: any) => { return (element.selected === true) });
|
||||
}
|
||||
|
||||
private removeSeletedItems(originList: any, selectedItemList) {
|
||||
for (let index = originList.length - 1; index >= 0; index--) {
|
||||
if (selectedItemList.some(elementToRemove => { return originList[index].workbasketId === elementToRemove.workbasketId })) {
|
||||
originList.splice(index, 1);
|
||||
}
|
||||
}
|
||||
return originList;
|
||||
|
||||
}
|
||||
|
||||
private ngOnDestroy(): void {
|
||||
if (this.distributionTargetsSubscription) { this.distributionTargetsSubscription.unsubscribe(); }
|
||||
if (this.workbasketSubscription) { this.workbasketSubscription.unsubscribe(); }
|
||||
if (this.workbasketFilterSubscription) { this.workbasketFilterSubscription.unsubscribe(); }
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<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 *ngIf="workbasket" id="wb-information" class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<div class="btn-group pull-right">
|
||||
<button type="button" [disabled]="!WorkbasketForm.form.valid" (click)="onSave()" class="btn btn-default btn-primary">Save</button>
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
<taskana-workbasket-access-items [workbasket]="workbasket"></taskana-workbasket-access-items>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane inactive" id="distribution-targets">
|
||||
<!-- <taskana-workbasket-distributiontargets [workbasket]="workbasket"></taskana-workbasket-distributiontargets>-->
|
||||
<taskana-workbaskets-distribution-targets [workbasket]="workbasket"></taskana-workbaskets-distribution-targets>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,14 +1,17 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { Component } from '@angular/core';
|
||||
import { async, ComponentFixture, TestBed, } from '@angular/core/testing';
|
||||
import { WorkbasketDetailsComponent } from './workbasket-details.component';
|
||||
import { NoAccessComponent } from '../noAccess/no-access.component';
|
||||
import { WorkbasketInformationComponent } from './information/workbasket-information.component';
|
||||
import { AccessItemsComponent } from './access-items/access-items.component';
|
||||
import { DistributionTargetsComponent } from './distribution-targets/distribution-targets.component';
|
||||
import { Workbasket } from 'app/model/workbasket';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { SpinnerComponent } from '../../shared/spinner/spinner.component';
|
||||
import { ICONTYPES, IconTypeComponent } from '../../shared/type-icon/icon-type.component';
|
||||
import { MapValuesPipe } from '../../pipes/map-values.pipe';
|
||||
import { RemoveNoneTypePipe } from '../../pipes/remove-none-type';
|
||||
import { SelectWorkBasketPipe } from '../../pipes/seleted-workbasket.pipe';
|
||||
import { AlertComponent } from '../../shared/alert/alert.component';
|
||||
import { GeneralMessageModalComponent } from '../../shared/general-message-modal/general-message-modal.component';
|
||||
import { Links } from 'app/model/links';
|
||||
|
@ -26,6 +29,15 @@ import { HttpClientModule } from '@angular/common/http';
|
|||
import { HttpModule } from '@angular/http';
|
||||
import { WorkbasketSummary } from '../../model/workbasketSummary';
|
||||
|
||||
@Component({
|
||||
selector: 'taskana-filter',
|
||||
template: ''
|
||||
})
|
||||
export class FilterComponent {
|
||||
|
||||
}
|
||||
|
||||
|
||||
describe('WorkbasketDetailsComponent', () => {
|
||||
let component: WorkbasketDetailsComponent;
|
||||
let fixture: ComponentFixture<WorkbasketDetailsComponent>;
|
||||
|
@ -33,10 +45,11 @@ describe('WorkbasketDetailsComponent', () => {
|
|||
let masterAndDetailService;
|
||||
let workbasketService;
|
||||
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [RouterTestingModule, FormsModule, AngularSvgIconModule, HttpClientModule, HttpModule],
|
||||
declarations: [ WorkbasketDetailsComponent, NoAccessComponent, WorkbasketInformationComponent, SpinnerComponent, IconTypeComponent, MapValuesPipe, RemoveNoneTypePipe, AlertComponent, GeneralMessageModalComponent, AccessItemsComponent ],
|
||||
declarations: [WorkbasketDetailsComponent, NoAccessComponent, WorkbasketInformationComponent, SpinnerComponent, IconTypeComponent, MapValuesPipe, RemoveNoneTypePipe, AlertComponent, GeneralMessageModalComponent, AccessItemsComponent, DistributionTargetsComponent, FilterComponent, SelectWorkBasketPipe],
|
||||
providers: [WorkbasketService, MasterAndDetailService, PermissionService, AlertService]
|
||||
})
|
||||
.compileComponents();
|
||||
|
@ -54,6 +67,7 @@ describe('WorkbasketDetailsComponent', () => {
|
|||
spyOn(workbasketService, 'getWorkBasketsSummary').and.callFake(() => { return Observable.of(new Array<WorkbasketSummary>(new WorkbasketSummary('id1', '', '', '', '', '', '', '', '', '', '', '', new Array<Links>(new Links('self', 'someurl'))))) })
|
||||
spyOn(workbasketService, 'getWorkBasket').and.callFake(() => { return Observable.of(new Workbasket('id1')) })
|
||||
spyOn(workbasketService, 'getWorkBasketAccessItems').and.callFake(() => { return Observable.of(new Array<WorkbasketAccessItems>()) })
|
||||
spyOn(workbasketService, 'getWorkBasketsDistributionTargets').and.callFake(() => { return Observable.of(new Array<WorkbasketSummary>()) })
|
||||
|
||||
});
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
<div class="clearfix btn-group">
|
||||
<button class="btn btn-default collapsed" type="button" id="collapsedMenufilterWb" data-toggle="collapse" data-target="#wb-filter-bar"
|
||||
aria-expanded="false">
|
||||
<span class="glyphicon glyphicon-filter blue wb-filter-toggle"></span>
|
||||
<span class="glyphicon glyphicon-filter blue"></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -155,10 +155,6 @@ li > div.row > dl {
|
|||
padding-right: 0px;
|
||||
}
|
||||
|
||||
.list-group-seach {
|
||||
padding: 10px 15px;
|
||||
}
|
||||
|
||||
.user-select {
|
||||
margin-left: 2px;
|
||||
}
|
||||
|
@ -198,36 +194,6 @@ li > div.row > dl {
|
|||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.btn-users-list {
|
||||
border: 0px solid transparent;
|
||||
/* this was 1px earlier */
|
||||
}
|
||||
|
||||
.dual-list .list-group {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.list-left li,
|
||||
.list-right li {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.list-arrows {
|
||||
padding-top: 100px;
|
||||
}
|
||||
|
||||
.list-arrows button {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.well-dual-list {
|
||||
min-height: 20px;
|
||||
padding: 5px;
|
||||
background-color: #f5f5f5;
|
||||
border: 1px solid #e3e3e3;
|
||||
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);
|
||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);
|
||||
}
|
||||
|
||||
.toolbar {
|
||||
padding: 13px 15px;
|
||||
|
@ -254,3 +220,10 @@ li > div.row > dl {
|
|||
.panel-heading{
|
||||
min-height: 60px;
|
||||
}
|
||||
.panel {
|
||||
border-radius: 0px;
|
||||
}
|
||||
|
||||
.centered-spinner {
|
||||
margin-top: 100px;
|
||||
}
|
Loading…
Reference in New Issue