TSK-201 Add Distribution targets saving feature.
This commit is contained in:
parent
5de0cd5e09
commit
5778ac75c0
|
@ -20,6 +20,7 @@ import { WorkbasketListComponent } from './workbasket/list/workbasket-list.compo
|
|||
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 { DualListComponent } from './workbasket/details/distribution-targets/dual-list/dual-list.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';
|
||||
|
@ -77,6 +78,7 @@ const DECLARATIONS = [
|
|||
GeneralMessageModalComponent,
|
||||
DistributionTargetsComponent,
|
||||
SortComponent,
|
||||
DualListComponent,
|
||||
MapValuesPipe,
|
||||
RemoveNoneTypePipe,
|
||||
SelectWorkBasketPipe
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
import { WorkbasketSummary } from './workbasket-summary';
|
||||
import { Links } from './links';
|
||||
|
||||
export class WorkbasketDistributionTargetsResource {
|
||||
constructor(public _embedded: {'distributionTargets': Array<WorkbasketSummary> } = {'distributionTargets': []}, public _links: Links = null) {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
import {Links} from './links';
|
||||
|
||||
export class WorkbasketSummary {
|
||||
constructor(
|
||||
public workbasketId: string,
|
||||
public key: string,
|
||||
public name: string,
|
||||
public description: string,
|
||||
public owner: string,
|
||||
public modified: string,
|
||||
public domain: string,
|
||||
public type: string,
|
||||
public orgLevel1: string,
|
||||
public orgLevel2: string,
|
||||
public orgLevel3: string,
|
||||
public orgLevel4: string,
|
||||
public links: Array<Links> = undefined){}
|
||||
}
|
|
@ -4,7 +4,7 @@ import { Pipe, PipeTransform } from '@angular/core';
|
|||
export class SelectWorkBasketPipe implements PipeTransform {
|
||||
transform(originArray: any, selectionArray: any, arg1: any): Object[] {
|
||||
let returnArray = [];
|
||||
if (!originArray) {
|
||||
if (!originArray || !selectionArray) {
|
||||
return returnArray;
|
||||
}
|
||||
|
||||
|
@ -17,5 +17,4 @@ export class SelectWorkBasketPipe implements PipeTransform {
|
|||
returnArray = originArray;
|
||||
return returnArray;
|
||||
}
|
||||
|
||||
}
|
|
@ -10,6 +10,7 @@ import { Subject } from 'rxjs/Subject';
|
|||
import { map } from 'rxjs/operator/map';
|
||||
import { WorkbasketSummaryResource } from '../model/workbasket-summary-resource';
|
||||
import { WorkbasketAccessItemsResource } from '../model/workbasket-access-items-resource';
|
||||
import { WorkbasketDistributionTargetsResource } from '../model/workbasket-distribution-targets-resource';
|
||||
|
||||
@Injectable()
|
||||
export class WorkbasketService {
|
||||
|
@ -100,8 +101,13 @@ export class WorkbasketService {
|
|||
this.httpOptions);
|
||||
}
|
||||
// GET
|
||||
getWorkBasketsDistributionTargets(url: string): Observable<WorkbasketSummaryResource> {
|
||||
return this.httpClient.get<WorkbasketSummaryResource>(url, this.httpOptions);
|
||||
getWorkBasketsDistributionTargets(url: string): Observable<WorkbasketDistributionTargetsResource> {
|
||||
return this.httpClient.get<WorkbasketDistributionTargetsResource>(url, this.httpOptions);
|
||||
}
|
||||
|
||||
// PUT
|
||||
updateWorkBasketsDistributionTargets(url: string, distributionTargetsIds :Array<string>): Observable<WorkbasketDistributionTargetsResource> {
|
||||
return this.httpClient.put<WorkbasketDistributionTargetsResource>(url, distributionTargetsIds, this.httpOptions);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -5,11 +5,12 @@
|
|||
margin-left: 15px;
|
||||
}
|
||||
|
||||
.list-group-search {
|
||||
padding: 10px 15px;
|
||||
}
|
||||
|
||||
.btn-users-list {
|
||||
border: 0px solid transparent;
|
||||
/* this was 1px earlier */
|
||||
}
|
||||
|
||||
.list-group-search {
|
||||
padding: 10px 15px;
|
||||
margin-top: 12px;
|
||||
border-top: 1px solid #ddd;
|
||||
}
|
|
@ -1 +1 @@
|
|||
.word-break{word-break: break-all; }
|
||||
.word-break{word-break: break-word; }
|
|
@ -1,4 +1,4 @@
|
|||
import { Component, OnInit, Input, ViewChild, OnChanges, SimpleChanges } from '@angular/core';
|
||||
import { Component, OnInit, Input, ViewChild, OnChanges, SimpleChanges, Output, EventEmitter, DoCheck } from '@angular/core';
|
||||
declare var $: any;
|
||||
|
||||
@Component({
|
||||
|
@ -8,8 +8,8 @@ declare var $: any;
|
|||
})
|
||||
export class GeneralMessageModalComponent implements OnChanges {
|
||||
|
||||
@Input()
|
||||
message: string = '';
|
||||
@Input() message: string;
|
||||
@Output() messageChange = new EventEmitter<string>();
|
||||
|
||||
@Input()
|
||||
title: string = '';
|
||||
|
@ -29,7 +29,8 @@ export class GeneralMessageModalComponent implements OnChanges {
|
|||
}
|
||||
|
||||
removeMessage() {
|
||||
this.message = undefined;
|
||||
this.message = '';
|
||||
this.messageChange.emit(this.message);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Component, Input, ElementRef } from '@angular/core';
|
||||
import { Component, Input, ElementRef, Output, EventEmitter } from '@angular/core';
|
||||
import { ViewChild } from '@angular/core';
|
||||
declare var $: any;
|
||||
|
||||
|
@ -9,11 +9,13 @@ declare var $: any;
|
|||
})
|
||||
export class SpinnerComponent {
|
||||
private currentTimeout: any;
|
||||
private requestTimeout: any;
|
||||
private maxRequestTimeout: number = 10000;
|
||||
|
||||
isDelayedRunning: boolean = false;
|
||||
|
||||
@Input()
|
||||
delay: number = 100;
|
||||
delay: number = 200;
|
||||
|
||||
@Input()
|
||||
set isRunning(value: boolean) {
|
||||
|
@ -37,6 +39,8 @@ export class SpinnerComponent {
|
|||
@Input()
|
||||
positionClass: string = undefined;
|
||||
|
||||
@Output()
|
||||
requestTimeoutExceeded = new EventEmitter<string>()
|
||||
|
||||
@ViewChild('spinnerModal')
|
||||
private modal;
|
||||
|
@ -46,6 +50,11 @@ export class SpinnerComponent {
|
|||
if (this.isModal) { $(this.modal.nativeElement).modal('toggle'); }
|
||||
this.isDelayedRunning = value;
|
||||
this.cancelTimeout();
|
||||
this.requestTimeout = setTimeout(() => {
|
||||
this.requestTimeoutExceeded.emit('There was an error with your request, please make sure you have internet connection');
|
||||
this.cancelTimeout();
|
||||
this.isRunning = false;
|
||||
},this.maxRequestTimeout);
|
||||
}, this.delay);
|
||||
}
|
||||
private closeModal() {
|
||||
|
@ -57,7 +66,9 @@ export class SpinnerComponent {
|
|||
|
||||
private cancelTimeout(): void {
|
||||
clearTimeout(this.currentTimeout);
|
||||
clearTimeout(this.requestTimeout);
|
||||
this.currentTimeout = undefined;
|
||||
this.requestTimeout = undefined;
|
||||
}
|
||||
|
||||
ngOnDestroy(): any {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<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>
|
||||
<taskana-general-message-modal *ngIf="modalErrorMessage" [(message)]="modalErrorMessage" [title]="modalTitle" error="true"></taskana-general-message-modal>
|
||||
<div *ngIf="workbasket && accessItems" id="wb-information" class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<div class="btn-group pull-right">
|
||||
|
@ -58,7 +58,7 @@
|
|||
<td [ngClass]="{'has-changes': (accessItemsClone[index].permAppend !== accessItem.permAppend)}">
|
||||
<input type="checkbox" name="accessItem.permAppend-{{index}}" [(ngModel)]="accessItem.permAppend">
|
||||
</td>
|
||||
<td ngClass="{{(accessItemsClone[index].permTransfer != accessItem.permTransfer)? 'has-changes': 'pepe'}}">
|
||||
<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 !== accessItem.permDistribute)}">
|
||||
|
|
|
@ -36,7 +36,7 @@ export class AccessItemsComponent implements OnInit {
|
|||
ngOnInit() {
|
||||
this.accessItemsubscription = this.workbasketService.getWorkBasketAccessItems(this.workbasket._links.accessItems.href).subscribe( (accessItemsResource: WorkbasketAccessItemsResource) =>{
|
||||
this.accessItemsResource = accessItemsResource;
|
||||
this.accessItems = accessItemsResource._embedded.accessItems;
|
||||
this.accessItems = accessItemsResource._embedded?accessItemsResource._embedded.accessItems: [];
|
||||
this.accessItemsClone = this.cloneAccessItems(this.accessItems);
|
||||
this.accessItemsResetClone = this.cloneAccessItems(this.accessItems);
|
||||
})
|
||||
|
@ -61,7 +61,7 @@ export class AccessItemsComponent implements OnInit {
|
|||
|
||||
onSave(): boolean {
|
||||
this.requestInProgress = true;
|
||||
this.workbasketService.updateWorkBasketAccessItem(this.accessItemsResource._links.self.href + '/', this.accessItems).subscribe(response =>{
|
||||
this.workbasketService.updateWorkBasketAccessItem(this.accessItemsResource._links.self.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.name} Access items were saved successfully`));
|
||||
|
|
|
@ -1,101 +1,34 @@
|
|||
<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>
|
||||
<taskana-spinner [isRunning]="requestInProgress" isModal="true" (requestTimeoutExceeded)="requestTimeoutExceeded($event)"
|
||||
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>
|
||||
<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">
|
||||
<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>
|
||||
<taskana-dual-list id="dual-list-Left" [(distributionTargets)]="distributionTargetsLeft" [distributionTargetsSelected]="distributionTargetsSelected"
|
||||
(performDualListFilter)="performFilter($event)" [side]="side.LEFT" [requestInProgress]="requestInProgressLeft" class="dual-list list-left col-xs-12 col-md-5-6 container"></taskana-dual-list>
|
||||
<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">
|
||||
<button (click)="moveDistributionTargets(side.LEFT)" [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">
|
||||
<button (click)="moveDistributionTargets(side.RIGHT)" [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">
|
||||
<button (click)="moveDistributionTargets(side.LEFT)" [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">
|
||||
<button (click)="moveDistributionTargets(side.RIGHT)" [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.select" type="text" (click)="distributionTarget.select = !distributionTarget.select">
|
||||
<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>
|
||||
<taskana-dual-list id="dual-list-right" [(distributionTargets)]="distributionTargetsRight" [distributionTargetsSelected]="distributionTargetsSelected"
|
||||
(performDualListFilter)="performFilter($event)" [requestInProgress]="requestInProgressRight" [side]="side.RIGHT" class="dual-list list-right col-xs-12 col-md-5-6 container"></taskana-dual-list>
|
||||
</div>
|
||||
</div>
|
|
@ -1,13 +1,4 @@
|
|||
|
||||
.list-group {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.list-left li,
|
||||
.list-right li {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.button-margin-top {
|
||||
margin-top: 100px
|
||||
}
|
||||
|
@ -16,25 +7,6 @@
|
|||
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){
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import { Input } from '@angular/core';
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { AngularSvgIconModule } from 'angular-svg-icon';
|
||||
import { HttpClientModule } from '@angular/common/http';
|
||||
import { HttpModule, JsonpModule } from '@angular/http';
|
||||
|
||||
import { DistributionTargetsComponent } from './distribution-targets.component';
|
||||
import { DistributionTargetsComponent, Side } from './distribution-targets.component';
|
||||
import { SpinnerComponent } from '../../../shared/spinner/spinner.component';
|
||||
import { GeneralMessageModalComponent } from '../../../shared/general-message-modal/general-message-modal.component';
|
||||
import { IconTypeComponent } from '../../../shared/type-icon/icon-type.component';
|
||||
|
@ -16,6 +17,9 @@ import { WorkbasketService } from '../../../services/workbasket.service';
|
|||
import { AlertService } from '../../../services/alert.service';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { Workbasket } from '../../../model/workbasket';
|
||||
import { WorkbasketDistributionTargetsResource } from '../../../model/workbasket-distribution-targets-resource';
|
||||
import { FilterModel } from '../../../shared/filter/filter.component';
|
||||
import { DualListComponent } from './dual-list/dual-list.component';
|
||||
|
||||
const workbasketSummaryResource: WorkbasketSummaryResource = new WorkbasketSummaryResource({
|
||||
'workbaskets': new Array<WorkbasketSummary>(
|
||||
|
@ -26,9 +30,12 @@ const workbasketSummaryResource: WorkbasketSummaryResource = new WorkbasketSumma
|
|||
@Component({
|
||||
selector: 'taskana-filter',
|
||||
template: ''
|
||||
|
||||
})
|
||||
export class FilterComponent {
|
||||
|
||||
@Input()
|
||||
target: string;
|
||||
}
|
||||
|
||||
|
||||
|
@ -41,7 +48,7 @@ describe('DistributionTargetsComponent', () => {
|
|||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [AngularSvgIconModule, HttpClientModule, HttpModule, JsonpModule],
|
||||
declarations: [DistributionTargetsComponent, SpinnerComponent, GeneralMessageModalComponent, FilterComponent, SelectWorkBasketPipe, IconTypeComponent],
|
||||
declarations: [DistributionTargetsComponent, SpinnerComponent, GeneralMessageModalComponent, FilterComponent, SelectWorkBasketPipe, IconTypeComponent, DualListComponent],
|
||||
providers: [WorkbasketService, AlertService]
|
||||
})
|
||||
.compileComponents();
|
||||
|
@ -54,11 +61,16 @@ describe('DistributionTargetsComponent', () => {
|
|||
workbasketService = TestBed.get(WorkbasketService);
|
||||
spyOn(workbasketService, 'getWorkBasketsSummary').and.callFake(() => {
|
||||
return Observable.of(new WorkbasketSummaryResource(
|
||||
{ 'workbaskets': new Array<WorkbasketSummary>(new WorkbasketSummary('id1', '', '', '', '', '', '', '', '', '', '', '', new Links({ 'href': 'someurl' }))) }, new Links({ 'href': 'someurl' })))
|
||||
{
|
||||
'workbaskets': new Array<WorkbasketSummary>(
|
||||
new WorkbasketSummary('id1', '', '', '', '', '', '', '', '', '', '', '', new Links({ 'href': 'someurl' })),
|
||||
new WorkbasketSummary('id2', '', '', '', '', '', '', '', '', '', '', '', new Links({ 'href': 'someurl' })),
|
||||
new WorkbasketSummary('id3', '', '', '', '', '', '', '', '', '', '', '', new Links({ 'href': 'someurl' })))
|
||||
}, new Links({ 'href': 'someurl' })))
|
||||
})
|
||||
spyOn(workbasketService, 'getWorkBasketsDistributionTargets').and.callFake(() => {
|
||||
return Observable.of(new WorkbasketSummaryResource(
|
||||
{ 'workbaskets': new Array<WorkbasketSummary>(new WorkbasketSummary('id1', '', '', '', '', '', '', '', '', '', '', '', new Links({ 'href': 'someurl' }))) }, new Links({ 'href': 'someurl' })))
|
||||
return Observable.of(new WorkbasketDistributionTargetsResource(
|
||||
{ 'distributionTargets': new Array<WorkbasketSummary>(new WorkbasketSummary('id2', '', '', '', '', '', '', '', '', '', '', '', new Links({ 'href': 'someurl' }))) }, new Links({ 'href': 'someurl' })))
|
||||
})
|
||||
|
||||
fixture.detectChanges();
|
||||
|
@ -67,4 +79,66 @@ describe('DistributionTargetsComponent', () => {
|
|||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
|
||||
|
||||
it('should clone distribution target selected on init', () => {
|
||||
expect(component.distributionTargetsClone).toBeDefined();
|
||||
});
|
||||
it('should clone distribution target left and distribution target right lists on init', () => {
|
||||
expect(component.distributionTargetsLeft).toBeDefined();
|
||||
expect(component.distributionTargetsRight).toBeDefined();
|
||||
});
|
||||
|
||||
it('should have two list with differents elements onInit', () => {
|
||||
let repeteadElemens = false;
|
||||
expect(component.distributionTargetsLeft.length).toBe(2);
|
||||
expect(component.distributionTargetsRight.length).toBe(1);
|
||||
component.distributionTargetsLeft.forEach(leftElement => {
|
||||
component.distributionTargetsRight.forEach(rightElement => {
|
||||
if (leftElement.workbasketId === rightElement.workbasketId) repeteadElemens = true;
|
||||
})
|
||||
})
|
||||
expect(repeteadElemens).toBeFalsy();
|
||||
});
|
||||
it('should filter left list and keep selected elements as selected', () => {
|
||||
component.performFilter({filterBy:new FilterModel(), side: Side.LEFT});
|
||||
component.distributionTargetsLeft = new Array<WorkbasketSummary>(
|
||||
new WorkbasketSummary('id1', '', '', '', '', '', '', '', '', '', '', '', new Links({ 'href': 'someurl' }))
|
||||
)
|
||||
expect(component.distributionTargetsLeft.length).toBe(1);
|
||||
expect(component.distributionTargetsLeft[0].workbasketId).toBe('id1');
|
||||
expect(component.distributionTargetsRight.length).toBe(1);
|
||||
expect(component.distributionTargetsRight[0].workbasketId).toBe('id2');
|
||||
});
|
||||
it('should reset distribution target and distribution target selected on reset', () => {
|
||||
component.distributionTargetsLeft.push(new WorkbasketSummary('id4', '', '', '', '', '', '', '', '', '', '', '', new Links({ 'href': 'someurl' })));
|
||||
component.distributionTargetsRight.push(new WorkbasketSummary('id5', '', '', '', '', '', '', '', '', '', '', '', new Links({ 'href': 'someurl' })));
|
||||
|
||||
expect(component.distributionTargetsLeft.length).toBe(3);
|
||||
expect(component.distributionTargetsRight.length).toBe(2);
|
||||
|
||||
component.onClear();
|
||||
fixture.detectChanges();
|
||||
expect(component.distributionTargetsLeft.length).toBe(2);
|
||||
expect(component.distributionTargetsRight.length).toBe(1)
|
||||
});
|
||||
|
||||
it('should save distribution targets selected and update Clone objects.', () => {
|
||||
expect(component.distributionTargetsSelected.length).toBe(1);
|
||||
expect(component.distributionTargetsSelectedClone.length).toBe(1);
|
||||
spyOn(workbasketService, 'updateWorkBasketsDistributionTargets').and.callFake(() => {
|
||||
return Observable.of(new WorkbasketDistributionTargetsResource(
|
||||
{
|
||||
'distributionTargets': new Array<WorkbasketSummary>(
|
||||
new WorkbasketSummary('id2', '', '', '', '', '', '', '', '', '', '', '', new Links({ 'href': 'someurl' })),
|
||||
new WorkbasketSummary('id1', '', '', '', '', '', '', '', '', '', '', '', new Links({ 'href': 'someurl' })))
|
||||
}, new Links({ 'href': 'someurl' })))
|
||||
})
|
||||
component.onSave();
|
||||
fixture.detectChanges();
|
||||
expect(component.distributionTargetsSelected.length).toBe(2);
|
||||
expect(component.distributionTargetsSelectedClone.length).toBe(2);
|
||||
expect(component.distributionTargetsLeft.length).toBe(1);
|
||||
|
||||
});
|
||||
});
|
||||
|
|
|
@ -3,6 +3,7 @@ import { Workbasket } from '../../../model/workbasket';
|
|||
import { WorkbasketSummary } from '../../../model/workbasket-summary';
|
||||
import { WorkbasketAccessItems } from '../../../model/workbasket-access-items';
|
||||
import { FilterModel } from '../../../shared/filter/filter.component'
|
||||
import { TREE_ACTIONS, KEYS, IActionMapping, ITreeOptions } from 'angular-tree-component';
|
||||
|
||||
import { WorkbasketService } from '../../../services/workbasket.service';
|
||||
import { AlertService, AlertModel, AlertType } from '../../../services/alert.service';
|
||||
|
@ -10,7 +11,12 @@ import { AlertService, AlertModel, AlertType } from '../../../services/alert.ser
|
|||
import { Subscription } from 'rxjs';
|
||||
import { element } from 'protractor';
|
||||
import { WorkbasketSummaryResource } from '../../../model/workbasket-summary-resource';
|
||||
import { WorkbasketDistributionTargetsResource } from '../../../model/workbasket-distribution-targets-resource';
|
||||
|
||||
export enum Side {
|
||||
LEFT,
|
||||
RIGHT
|
||||
}
|
||||
@Component({
|
||||
selector: 'taskana-workbaskets-distribution-targets',
|
||||
templateUrl: './distribution-targets.component.html',
|
||||
|
@ -24,54 +30,45 @@ export class DistributionTargetsComponent implements OnInit {
|
|||
distributionTargetsSubscription: Subscription;
|
||||
workbasketSubscription: Subscription;
|
||||
workbasketFilterSubscription: Subscription;
|
||||
distributionTargetsResource: WorkbasketSummaryResource;
|
||||
distributionTargetsLeft: Array<WorkbasketSummary> = [];
|
||||
distributionTargetsRight: Array<WorkbasketSummary> = [];
|
||||
distributionTargetsSelected: Array<WorkbasketSummary> = [];
|
||||
|
||||
distributionTargetsSelectedResource: WorkbasketDistributionTargetsResource;
|
||||
distributionTargetsLeft: Array<WorkbasketSummary>;
|
||||
distributionTargetsRight: Array<WorkbasketSummary>;
|
||||
distributionTargetsSelected: Array<WorkbasketSummary>;
|
||||
distributionTargetsClone: Array<WorkbasketSummary>;
|
||||
distributionTargetsSelectedClone: Array<WorkbasketSummary>;
|
||||
|
||||
|
||||
filterBy: FilterModel = new FilterModel();
|
||||
requestInProgress: boolean = false;
|
||||
requestInProgressLeft: boolean = false;
|
||||
requestInProgressRight: boolean = false;
|
||||
modalErrorMessage: string;
|
||||
side = Side;
|
||||
|
||||
constructor(private workbasketService: WorkbasketService) { }
|
||||
constructor(private workbasketService: WorkbasketService, private alertService: AlertService) { }
|
||||
|
||||
ngOnInit() {
|
||||
this.requestInProgressLeft = true;
|
||||
this.requestInProgressRight = true;
|
||||
this.distributionTargetsSubscription = this.workbasketService.getWorkBasketsDistributionTargets(this.workbasket._links.distributionTargets.href).subscribe((distributionTargetsSelectedResource: WorkbasketSummaryResource) => {
|
||||
this.distributionTargetsSelected = distributionTargetsSelectedResource._embedded ? distributionTargetsSelectedResource._embedded.workbaskets :[];
|
||||
this.onRequest(undefined);
|
||||
this.distributionTargetsSubscription = this.workbasketService.getWorkBasketsDistributionTargets(this.workbasket._links.distributionTargets.href).subscribe((distributionTargetsSelectedResource: WorkbasketDistributionTargetsResource) => {
|
||||
this.distributionTargetsSelectedResource = distributionTargetsSelectedResource;
|
||||
this.distributionTargetsSelected = distributionTargetsSelectedResource._embedded ? distributionTargetsSelectedResource._embedded.distributionTargets : [];
|
||||
this.distributionTargetsSelectedClone = Object.assign([], this.distributionTargetsSelected);
|
||||
this.workbasketSubscription = this.workbasketService.getWorkBasketsSummary().subscribe((distributionTargetsAvailable: WorkbasketSummaryResource) => {
|
||||
this.distributionTargetsResource = distributionTargetsAvailable;
|
||||
this.distributionTargetsLeft = Object.assign([], distributionTargetsAvailable._embedded.workbaskets);
|
||||
this.distributionTargetsRight = Object.assign([], distributionTargetsAvailable._embedded.workbaskets);
|
||||
this.requestInProgressLeft = false;
|
||||
this.requestInProgressRight = false;
|
||||
this.distributionTargetsClone = Object.assign([], distributionTargetsAvailable._embedded.workbaskets);
|
||||
this.onRequest(undefined, true);
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
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) {
|
||||
if (side === Side.LEFT) {
|
||||
let itemsSelected = this.getSelectedItems(this.distributionTargetsLeft, this.distributionTargetsRight)
|
||||
this.distributionTargetsSelected = this.distributionTargetsSelected.concat(itemsSelected);
|
||||
this.distributionTargetsRight = this.distributionTargetsRight.concat(itemsSelected);
|
||||
}
|
||||
else if (side === 1) {
|
||||
else {
|
||||
let itemsSelected = this.getSelectedItems(this.distributionTargetsRight, this.distributionTargetsLeft);
|
||||
this.distributionTargetsSelected = this.removeSeletedItems(this.distributionTargetsSelected, itemsSelected);
|
||||
this.distributionTargetsRight = this.removeSeletedItems(this.distributionTargetsRight, itemsSelected);
|
||||
|
@ -79,29 +76,51 @@ export class DistributionTargetsComponent implements OnInit {
|
|||
}
|
||||
}
|
||||
|
||||
performAvailableFilter(filterBy: FilterModel) {
|
||||
this.filterBy = filterBy;
|
||||
this.performFilter(0);
|
||||
onSave() {
|
||||
this.requestInProgress = true;
|
||||
this.workbasketService.updateWorkBasketsDistributionTargets(this.distributionTargetsSelectedResource._links.self.href, this.getSeletedIds()).subscribe(response => {
|
||||
this.requestInProgress = false;
|
||||
this.distributionTargetsSelected = response._embedded ? response._embedded.distributionTargets : [];
|
||||
this.distributionTargetsSelectedClone = Object.assign([], this.distributionTargetsSelected);
|
||||
this.distributionTargetsClone = Object.assign([], this.distributionTargetsLeft);
|
||||
this.alertService.triggerAlert(new AlertModel(AlertType.SUCCESS, `Workbasket ${this.workbasket.name} Access items were saved successfully`));
|
||||
return true;
|
||||
},
|
||||
error => {
|
||||
this.modalErrorMessage = error.message;
|
||||
this.requestInProgress = false;
|
||||
return false;
|
||||
}
|
||||
performSelectedFilter(filterBy: FilterModel) {
|
||||
this.filterBy = filterBy;
|
||||
this.performFilter(1);
|
||||
)
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
private performFilter(listType: number) {
|
||||
onClear() {
|
||||
this.alertService.triggerAlert(new AlertModel(AlertType.INFO, 'Reset edited fields'))
|
||||
this.distributionTargetsLeft = Object.assign([], this.distributionTargetsClone);
|
||||
this.distributionTargetsRight = Object.assign([], this.distributionTargetsSelectedClone);
|
||||
this.distributionTargetsSelected = Object.assign([], this.distributionTargetsSelectedClone);
|
||||
}
|
||||
|
||||
listType ? this.distributionTargetsRight = undefined : this.distributionTargetsLeft = undefined;
|
||||
listType ? this.requestInProgressRight = true : this.requestInProgressLeft = true;
|
||||
requestTimeoutExceeded(message: string) {
|
||||
this.modalErrorMessage = message;
|
||||
}
|
||||
|
||||
performFilter(dualListFilter: any) {
|
||||
|
||||
dualListFilter.side === Side.RIGHT ? this.distributionTargetsRight = undefined : this.distributionTargetsLeft = undefined;
|
||||
this.onRequest(dualListFilter.side, false);
|
||||
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: WorkbasketSummaryResource) => {
|
||||
listType ? this.distributionTargetsRight = resultList._embedded.workbaskets : this.distributionTargetsLeft = resultList._embedded.workbaskets;
|
||||
listType ? this.requestInProgressRight = false : this.requestInProgressLeft = false;
|
||||
dualListFilter.filterBy.name, dualListFilter.filterBy.description, undefined, dualListFilter.filterBy.owner,
|
||||
dualListFilter.filterBy.type, undefined, dualListFilter.filterBy.key).subscribe(resultList => {
|
||||
(dualListFilter.side === Side.RIGHT) ?
|
||||
this.distributionTargetsRight = (resultList._embedded ? resultList._embedded.workbaskets : []) :
|
||||
this.distributionTargetsLeft = (resultList._embedded ? resultList._embedded.workbaskets : []);
|
||||
this.onRequest(dualListFilter.side, true);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
private getSelectedItems(originList: any, destinationList: any): Array<any> {
|
||||
return originList.filter((element: any) => { return (element.selected === true) });
|
||||
}
|
||||
|
@ -113,7 +132,24 @@ export class DistributionTargetsComponent implements OnInit {
|
|||
}
|
||||
}
|
||||
return originList;
|
||||
}
|
||||
|
||||
private onRequest(side: Side = undefined, finished: boolean = false) {
|
||||
if (finished) {
|
||||
side === undefined ? (this.requestInProgressLeft = false, this.requestInProgressRight = false) :
|
||||
side === Side.LEFT ? this.requestInProgressLeft = false : this.requestInProgressRight = false;
|
||||
return;
|
||||
}
|
||||
side === undefined ? (this.requestInProgressLeft = true, this.requestInProgressRight = true) :
|
||||
side === Side.LEFT ? this.requestInProgressLeft = true : this.requestInProgressRight = true;
|
||||
}
|
||||
|
||||
private getSeletedIds(): Array<string> {
|
||||
let distributionTargetsSelelected: Array<string> = [];
|
||||
this.distributionTargetsSelected.forEach(element => {
|
||||
distributionTargetsSelelected.push(element.workbasketId);
|
||||
})
|
||||
return distributionTargetsSelelected;
|
||||
}
|
||||
|
||||
private ngOnDestroy(): void {
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
<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(toggleDtl);" class="btn btn-default no-style" title="select all">
|
||||
<span aria-hidden="true" class="glyphicon blue {{toggleDtl? 'glyphicon-check': 'glyphicon-unchecked'}}"></span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-xs-7">
|
||||
<h5>Available distribution targets</h5>
|
||||
</div>
|
||||
<div class="pull-right">
|
||||
<button class="btn btn-default collapsed" type="button" id="collapsedMenufilterWbDta" data-toggle="collapse"
|
||||
[attr.data-target]="'#wb-dta-filter-bar-' + sideNumber"
|
||||
aria-expanded="false">
|
||||
<span class="glyphicon glyphicon-filter blue"></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<taskana-filter target="wb-dta-filter-bar-{{sideNumber}}" (performFilter)="performAvailableFilter($event)"></taskana-filter>
|
||||
<taskana-spinner [isRunning]="requestInProgress" positionClass="centered-spinner" class="centered-horizontally floating"></taskana-spinner>
|
||||
<ul class="list-group ">
|
||||
<li class="list-group-item" *ngFor="let distributionTarget of distributionTargets | selectWorkbaskets: distributionTargetsSelected: side"
|
||||
[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>
|
|
@ -0,0 +1,60 @@
|
|||
.dual-list {
|
||||
min-height: 300px;
|
||||
padding: 0px;
|
||||
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: 3px 0px 0px 3px;
|
||||
}
|
||||
& .row:first {
|
||||
border-top: 1px solid #ddd;
|
||||
}
|
||||
|
||||
& div.pull-right {
|
||||
margin-right: 18px;
|
||||
}
|
||||
|
||||
& >.list-group {
|
||||
margin-bottom: 0px;
|
||||
margin-top: 0px;
|
||||
|
||||
}
|
||||
& > .list-group > li {
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
overflow-x: hidden;
|
||||
overflow-y: scroll;
|
||||
|
||||
@media screen and (max-width: 991px){
|
||||
max-height: 38vh;
|
||||
}
|
||||
max-height: 78vh;
|
||||
|
||||
}
|
||||
|
||||
.list-group {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
|
||||
ul>li {
|
||||
&:first-child.list-group-item.selected {
|
||||
border-color: #ddd;
|
||||
}
|
||||
&.list-group-item.selected {
|
||||
background-color: #e9f2fc;
|
||||
}
|
||||
}
|
||||
|
||||
.list-left li {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
button.no-style{
|
||||
background: none;
|
||||
border:none;
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
|
||||
import { WorkbasketSummary } from '../../../../model/workbasket-summary';
|
||||
import { FilterModel } from '../../../../shared/filter/filter.component';
|
||||
import { filter } from 'rxjs/operators';
|
||||
import { Side } from '../distribution-targets.component';
|
||||
|
||||
@Component({
|
||||
selector: 'taskana-dual-list',
|
||||
templateUrl: './dual-list.component.html',
|
||||
styleUrls: ['./dual-list.component.scss']
|
||||
})
|
||||
export class DualListComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit() {
|
||||
this.sideNumber = this.side === Side.LEFT ? 0 : 1;
|
||||
}
|
||||
|
||||
@Input() distributionTargets: Array<WorkbasketSummary>;
|
||||
@Output() distributionTargetsChange = new EventEmitter<Array<WorkbasketSummary>>();
|
||||
@Input() distributionTargetsSelected: Array<WorkbasketSummary>;
|
||||
@Output() performDualListFilter = new EventEmitter<{ filterBy: FilterModel, side: Side }>();
|
||||
@Input() requestInProgress: boolean = false;
|
||||
|
||||
@Input() side: Side;
|
||||
sideNumber: number = 0;
|
||||
|
||||
selectAll(selected: boolean) {
|
||||
this.distributionTargets.forEach((element: any) => {
|
||||
element.selected = selected;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
performAvailableFilter(filterModel: FilterModel) {
|
||||
this.performDualListFilter.emit({ filterBy: filterModel, side: this.side });
|
||||
}
|
||||
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
<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>
|
||||
<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">
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<div class="container-scrollable" >
|
||||
<taskana-spinner [isRunning]="requestInProgress" class = "centered-horizontally"></taskana-spinner>
|
||||
<app-no-access *ngIf="!requestInProgress && (!hasPermission || !workbasket && selectedId)" ></app-no-access>
|
||||
<div id ="workbasket-details" class="workbasket-details" *ngIf="workbasket && !requestInProgress">
|
||||
<div id ="workbasket-details" *ngIf="workbasket && !requestInProgress">
|
||||
<ul class="nav nav-tabs" role="tablist">
|
||||
<li *ngIf="showDetail" class="visible-xs visible-sm hidden">
|
||||
<a (click) = "backClicked()"><span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>Back</a>
|
||||
|
@ -9,14 +9,14 @@
|
|||
<li role="presentation" class="active">
|
||||
<a href="#work-baskets" aria-controls="work baskets" role="tab" data-toggle="tab" aria-expanded="true">Information</a>
|
||||
</li>
|
||||
<li role="presentation" class="inactive">
|
||||
<li role="presentation" class="">
|
||||
<a href="#access-items" aria-controls="Acccess" role="tab" data-toggle="tab" aria-expanded="true">Access</a>
|
||||
</li>
|
||||
<li role="presentation" class="inactive">
|
||||
<li role="presentation" class="">
|
||||
<a href="#distribution-targets" aria-controls="distribution targets" role="tab" data-toggle="tab" aria-expanded="true">Distribution targets</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tab-content detail-tab-content">
|
||||
<div class="tab-content">
|
||||
<div role="tabpanel" class="tab-pane active" id="work-baskets">
|
||||
<workbasket-information [workbasket]="workbasket"></workbasket-information>
|
||||
</div>
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
.nav.nav-tabs {
|
||||
& > li {
|
||||
& > a {
|
||||
min-height: 56px;
|
||||
padding-top: 17px;
|
||||
min-height: 52px;
|
||||
padding-top: 15px;
|
||||
border-radius: 0px;
|
||||
&.has-changes{
|
||||
border-bottom: solid #f0ad4e;
|
||||
}
|
||||
|
@ -12,11 +13,12 @@
|
|||
border-left: none;
|
||||
}
|
||||
}
|
||||
& > li.active > a {
|
||||
border-top: 3px solid #479ea9;
|
||||
padding-top: 13px;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
& > p{
|
||||
margin: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
.workbasket-details{
|
||||
margin-top:1px;
|
||||
}
|
|
@ -1,10 +1,11 @@
|
|||
import { Component } from '@angular/core';
|
||||
import { Component, Input } 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 { DualListComponent } from './distribution-targets//dual-list/dual-list.component';
|
||||
import { Workbasket } from 'app/model/workbasket';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { SpinnerComponent } from '../../shared/spinner/spinner.component';
|
||||
|
@ -37,6 +38,8 @@ import { WorkbasketAccessItemsResource } from '../../model/workbasket-access-ite
|
|||
})
|
||||
export class FilterComponent {
|
||||
|
||||
@Input()
|
||||
target: string;
|
||||
}
|
||||
|
||||
|
||||
|
@ -52,7 +55,7 @@ describe('WorkbasketDetailsComponent', () => {
|
|||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [RouterTestingModule, FormsModule, AngularSvgIconModule, HttpClientModule, HttpModule],
|
||||
declarations: [WorkbasketDetailsComponent, NoAccessComponent, WorkbasketInformationComponent, SpinnerComponent, IconTypeComponent, MapValuesPipe, RemoveNoneTypePipe, AlertComponent, GeneralMessageModalComponent, AccessItemsComponent, DistributionTargetsComponent, FilterComponent, SelectWorkBasketPipe],
|
||||
declarations: [WorkbasketDetailsComponent, NoAccessComponent, WorkbasketInformationComponent, SpinnerComponent, IconTypeComponent, MapValuesPipe, RemoveNoneTypePipe, AlertComponent, GeneralMessageModalComponent, AccessItemsComponent, DistributionTargetsComponent, FilterComponent, DualListComponent, SelectWorkBasketPipe],
|
||||
providers: [WorkbasketService, MasterAndDetailService, PermissionService, AlertService]
|
||||
})
|
||||
.compileComponents();
|
||||
|
@ -73,8 +76,8 @@ describe('WorkbasketDetailsComponent', () => {
|
|||
})
|
||||
|
||||
spyOn(workbasketService, 'getWorkBasket').and.callFake(() => { return Observable.of(workbasket) })
|
||||
spyOn(workbasketService, 'getWorkBasketAccessItems').and.callFake(() => { return Observable.of(new WorkbasketAccessItemsResource( {'accessItems': new Array<WorkbasketAccessItems>()}, new Links({'href': 'url'})) )})
|
||||
spyOn(workbasketService, 'getWorkBasketsDistributionTargets').and.callFake(() => { return Observable.of(new WorkbasketSummaryResource( {'workbaskets': new Array<WorkbasketSummary>()}, new Links({'href': 'url'})) ) })
|
||||
spyOn(workbasketService, 'getWorkBasketAccessItems').and.callFake(() => { return Observable.of(new WorkbasketAccessItemsResource({ 'accessItems': new Array<WorkbasketAccessItems>() }, new Links({ 'href': 'url' }))) })
|
||||
spyOn(workbasketService, 'getWorkBasketsDistributionTargets').and.callFake(() => { return Observable.of(new WorkbasketSummaryResource({ 'workbaskets': new Array<WorkbasketSummary>() }, new Links({ 'href': 'url' }))) })
|
||||
|
||||
});
|
||||
|
||||
|
|
|
@ -17,5 +17,6 @@ a > label{
|
|||
}
|
||||
|
||||
.tab-align{
|
||||
border-bottom: 1px solid #ddd;
|
||||
padding-bottom: 12px;
|
||||
}
|
||||
|
|
|
@ -146,14 +146,6 @@ li > div.row > dl {
|
|||
color: red;
|
||||
}
|
||||
|
||||
.detail-tab-content {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.col-xs-9.mod-col-9 {
|
||||
width: 74%;
|
||||
padding-right: 0px;
|
||||
}
|
||||
|
||||
.user-select {
|
||||
margin-left: 2px;
|
||||
|
@ -225,5 +217,27 @@ li > div.row > dl {
|
|||
}
|
||||
|
||||
.centered-spinner {
|
||||
margin-top: 100px;
|
||||
margin-top: 30px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.list-group-item {
|
||||
padding: 5px 15px;
|
||||
}
|
||||
|
||||
.dual-list > taskana-filter >.list-group-search {
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
workbasket-information, taskana-workbasket-access-items, taskana-workbaskets-distribution-targets {
|
||||
&> .panel{
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
margin-bottom: 0px;
|
||||
&> .panel-body {
|
||||
height: 84vh;
|
||||
max-height: 84vh;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue