TSK-1517: Fix distribution targets moving and filtering

This commit is contained in:
Sofie Hofmann 2021-02-01 08:52:44 +01:00
parent 4d279c4871
commit abfa4e09fc
9 changed files with 204 additions and 190 deletions

View File

@ -1,7 +1,8 @@
<div id="dual-list-Left" class="distribution-targets-list">
<mat-toolbar>
<span class="distribution-targets-list__header">{{header}}</span>
<span class="distribution-targets-list__header" matTooltip="{{header}}">{{header}}</span>
<!-- FILTER BUTTON -->
<button mat-flat-button class="distribution-targets-list__action-button" (click)="changeToolbarState(!toolbarState)"
>
<span *ngIf="!toolbarState">
@ -16,29 +17,35 @@
<span style="flex: 1 1 auto"> </span>
<!-- SELECT ALL BUTTON -->
<button mat-flat-button class="distribution-targets-list__action-button" (click)="selectAll(allSelected);">
<mat-icon class="button-icon" *ngIf="!allSelected" matTooltip="Deselect all items">check_box</mat-icon>
<mat-icon class="button-icon" *ngIf="allSelected" matTooltip="Select all items">check_box_outline_blank</mat-icon>
</button>
</mat-toolbar>
<!-- FILTER COMPONENT -->
<taskana-shared-workbasket-filter *ngIf="toolbarState" (performFilter)="performAvailableFilter($event)"
isExpanded="true" component="distribution-target"></taskana-shared-workbasket-filter>
<!-- WORKBASKET LIST -->
<div class="distribution-targets-list__list" infiniteScroll [infiniteScrollDistance]="1" [infiniteScrollThrottle]="50" (scrolled)="onScroll()"
<div class="{{toolbarState? 'distribution-targets-list__list--with-filter' : 'distribution-targets-list__list--no-filter'}}"
infiniteScroll [infiniteScrollDistance]="1" [infiniteScrollThrottle]="50"
[scrollWindow]="false" *ngIf="distributionTargets?.length > 0">
<mat-selection-list #workbasket [multiple]="true">
<mat-list-option class="workbasket-distribution-targets__workbaskets-item"
*ngFor="let workbasket of distributionTargets | selectWorkbaskets: distributionTargetsSelected: side"
*ngFor="let workbasket of distributionTargets"
[selected]="workbasket.selected"
(click)="workbasket.selected = !workbasket.selected"
[value]="workbasket.workbasketId">
<div class="distribution-targets-list__item-wrapper">
<!-- ICON -->
<div class="distribution-targets-list__item-icon">
<taskana-administration-icon-type [type]="workbasket.type" size="large" tooltip="true"></taskana-administration-icon-type>
</div>
<!-- INFO -->
<div class="distribution-targets-list__item-info">
<p>
<b>{{workbasket.name}}</b>, <i>{{workbasket.key}} </i>
@ -47,6 +54,7 @@
<p>{{workbasket.owner}} &nbsp;</p>
</div>
<!-- MARKED FOR DELETION -->
<div class="workbaskets-item__marked" *ngIf="workbasket.markedForDeletion">
<span title="Marked for deletion" matTooltip="Marked for deletion"
class="material-icons md-20 {{workbasket.workbasketId === selectedId ? 'white': 'red' }} ">error</span>

View File

@ -12,7 +12,7 @@
margin-left: 0.5rem;
}
&__list {
&__list--no-filter {
min-width: 100%;
background-color: white;
border-radius: 10px;
@ -24,6 +24,18 @@
min-height: 83px;
}
}
&__list--with-filter {
min-width: 100%;
background-color: white;
border-radius: 10px;
overflow-y: scroll;
height: calc(100vh - 360px - 187px) !important;
@media screen and (max-width: 991px) {
height: calc((100vh - 315px - 187px));
min-height: 83px;
}
}
&__item-wrapper {
display: flex;
}

View File

@ -3,7 +3,6 @@ import { Component, DebugElement, EventEmitter, Input, Output } from '@angular/c
import { WorkbasketDistributionTargetsListComponent } from './workbasket-distribution-targets-list.component';
import { InfiniteScrollModule } from 'ngx-infinite-scroll';
import { WorkbasketType } from '../../../shared/models/workbasket-type';
import { SelectWorkBasketPipe } from '../../../shared/pipes/select-workbaskets.pipe';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { workbasketReadStateMock } from '../../../shared/store/mock-data/mock-store';
import { Side } from '../workbasket-distribution-targets/workbasket-distribution-targets.component';
@ -11,6 +10,7 @@ import { MatIconModule } from '@angular/material/icon';
import { MatToolbarModule } from '@angular/material/toolbar';
import { MatListModule } from '@angular/material/list';
import { WorkbasketQueryFilterParameter } from '../../../shared/models/workbasket-query-filter-parameter';
import { MatTooltipModule } from '@angular/material/tooltip';
@Component({ selector: 'taskana-shared-workbasket-filter', template: '' })
class FilterStub {
@ -35,14 +35,15 @@ describe('WorkbasketDistributionTargetsListComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [MatIconModule, MatToolbarModule, MatListModule, InfiniteScrollModule, BrowserAnimationsModule],
declarations: [
WorkbasketDistributionTargetsListComponent,
FilterStub,
SpinnerStub,
IconTypeStub,
SelectWorkBasketPipe
imports: [
MatIconModule,
MatToolbarModule,
MatListModule,
MatTooltipModule,
InfiniteScrollModule,
BrowserAnimationsModule
],
declarations: [WorkbasketDistributionTargetsListComponent, FilterStub, SpinnerStub, IconTypeStub],
providers: []
}).compileComponents();
@ -50,7 +51,6 @@ describe('WorkbasketDistributionTargetsListComponent', () => {
debugElement = fixture.debugElement;
component = fixture.componentInstance;
component.distributionTargets = workbasketReadStateMock.paginatedWorkbasketsSummary.workbaskets;
component.distributionTargetsSelected = [];
component.side = Side.AVAILABLE;
}));
@ -70,12 +70,6 @@ describe('WorkbasketDistributionTargetsListComponent', () => {
});
});
it('should emit side when scrolling', () => {
const scrollingEmitSpy = jest.spyOn(component.scrolling, 'emit');
component.onScroll();
expect(scrollingEmitSpy).toHaveBeenCalledWith(component.side);
});
it('should change toolbar state', () => {
expect(component.toolbarState).toBe(false);
component.changeToolbarState(true);

View File

@ -23,15 +23,10 @@ import { WorkbasketQueryFilterParameter } from '../../../shared/models/workbaske
})
export class WorkbasketDistributionTargetsListComponent implements OnInit, AfterContentChecked {
@Input() distributionTargets: WorkbasketSummary[];
@Input() distributionTargetsSelected: WorkbasketSummary[];
@Output() performDualListFilter = new EventEmitter<Pair<Side, WorkbasketQueryFilterParameter>>();
@Input() requestInProgress = false;
@Input() loadingItems? = false;
@Input() side: Side;
@Input() header: string;
@Output() scrolling = new EventEmitter<Side>();
@Input() allSelected;
@Output() allSelectedChange = new EventEmitter<boolean>();
@Output() performDualListFilter = new EventEmitter<Pair<Side, WorkbasketQueryFilterParameter>>();
toolbarState = false;
@ViewChild('workbasket') distributionTargetsList: MatSelectionList;
@ -52,11 +47,6 @@ export class WorkbasketDistributionTargetsListComponent implements OnInit, After
this.distributionTargetsList.options.map((item) => (item['selected'] = selected));
}
this.distributionTargets.map((item) => (item['selected'] = selected));
this.allSelectedChange.emit(this.allSelected);
}
onScroll() {
this.scrolling.emit(this.side);
}
performAvailableFilter(pair: Pair<string, WorkbasketQueryFilterParameter>) {

View File

@ -82,13 +82,10 @@
<taskana-administration-workbasket-distribution-targets-list
[ngClass]="sideBySide ? 'distribution-targets-list__lists--left-side' : ''"
header="Selected distribution targets"
[distributionTargets]="distributionTargetsLeft"
[distributionTargetsSelected]="distributionTargetsSelected"
[distributionTargets]="selectedDistributionTargets"
(performDualListFilter)="performFilter($event)"
[side]="side.SELECTED"
(scrolling)="onScroll()"
[loadingItems]="loadingItems"
[(allSelected)]="selectAllLeft"
[allSelected]="selectAllLeft"
[hidden]="displayingDistributionTargetsPicker && !sideBySide"
>
@ -98,11 +95,8 @@
header="Available distribution targets"
[distributionTargets]="availableDistributionTargets"
[side]="side.AVAILABLE"
[distributionTargetsSelected]="distributionTargetsSelected"
(performDualListFilter)="performFilter($event)"
(scrolling)="onScroll()"
[loadingItems]="loadingItems"
[(allSelected)]="selectAllRight"
[allSelected]="selectAllRight"
*ngIf="displayingDistributionTargetsPicker"
>

View File

@ -127,37 +127,62 @@ describe('WorkbasketDistributionTargetsComponent', () => {
});
it('should get available and selected distribution targets', () => {
component.getWorkbaskets();
expect(component.availableDistributionTargets).toHaveLength(8); //mock-data has 8 entries
expect(component.distributionTargetsSelected).toHaveLength(3); //mock-data has 3 entries
});
// mock-data has 8 entries, array should be filtered by selected distribution targets
expect(component.availableDistributionTargets).toHaveLength(5);
expect(component.availableDistributionTargetsUndoClone).toHaveLength(5);
expect(component.availableDistributionTargetsFilterClone).toHaveLength(5);
// TODO: was ist das für ein test?
it('should emit filter model and side when performing filter', () => {
const performDualListFilterSpy = jest.spyOn(component, 'performFilter');
const filterModelMock: WorkbasketQueryFilterParameter = { domain: ['DOMAIN_A'] };
component.performFilter({ left: Side.AVAILABLE, right: filterModelMock });
expect(performDualListFilterSpy).toHaveBeenCalledWith({ right: filterModelMock, left: Side.AVAILABLE });
// mock-data has 3 entries
expect(component.selectedDistributionTargets).toHaveLength(3);
expect(component.selectedDistributionTargetsUndoClone).toHaveLength(3);
expect(component.selectedDistributionTargetsFilterClone).toHaveLength(3);
});
it('should move distribution targets to selected list', () => {
component.availableDistributionTargets[0]['selected'] = true; // select first item in available array
component.distributionTargetsLeft = component.distributionTargetsSelected;
const removeSelectedItems = jest.spyOn(component, 'removeSelectedItems');
component.moveDistributionTargets(Side.AVAILABLE);
expect(component.distributionTargetsSelected).toHaveLength(4); // mock-data only has 3
expect(component.selectedDistributionTargets).toHaveLength(4); // mock-data only has 3
expect(component.selectedDistributionTargetsFilterClone).toHaveLength(4);
expect(removeSelectedItems).toHaveBeenCalled();
});
it('should move distribution targets to available list', () => {
component.selectedDistributionTargets[0]['selected'] = true; // select first item in available array
const removeSelectedItems = jest.spyOn(component, 'removeSelectedItems');
component.moveDistributionTargets(Side.SELECTED);
expect(component.availableDistributionTargets).toHaveLength(6); // mock-data has 5
expect(component.availableDistributionTargetsFilterClone).toHaveLength(6);
expect(removeSelectedItems).toHaveBeenCalled();
});
it('should set selectAll checkboxes to true when moving a workbasket', () => {
[Side.SELECTED, Side.AVAILABLE].forEach((side) => {
component.moveDistributionTargets(side);
expect(component.selectAllLeft).toBeTruthy();
expect(component.selectAllRight).toBeTruthy();
});
});
it('should call unselectItems() when moving a workbasket', () => {
const unselectItems = jest.spyOn(component, 'unselectItems');
[Side.SELECTED, Side.AVAILABLE].forEach((side) => {
component.moveDistributionTargets(side);
expect(unselectItems).toHaveBeenCalled();
});
});
it('should reset distribution targets to last state when undo is called', () => {
component.distributionTargetsClone = component.availableDistributionTargets;
component.distributionTargetsSelectedClone = component.distributionTargetsSelected;
component.availableDistributionTargets[0]['selected'] = true; // select first item in available array
component.distributionTargetsLeft = component.distributionTargetsSelected;
component.moveDistributionTargets(Side.AVAILABLE);
expect(component.distributionTargetsSelected).toHaveLength(4); // mock-data only has 3
expect(component.selectedDistributionTargets).toHaveLength(4); // mock-data only has 3
component.onClear();
expect(component.distributionTargetsSelected).toHaveLength(3);
expect(component.selectedDistributionTargets).toHaveLength(3);
expect(component.selectedDistributionTargetsFilterClone).toHaveLength(3);
});
});

View File

@ -1,4 +1,4 @@
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
import { Component, Input, OnDestroy, OnInit, SimpleChanges } from '@angular/core';
import { Observable, Subject } from 'rxjs';
import { Workbasket } from 'app/shared/models/workbasket';
@ -6,7 +6,6 @@ import { WorkbasketSummary } from 'app/shared/models/workbasket-summary';
import { WorkbasketSummaryRepresentation } from 'app/shared/models/workbasket-summary-representation';
import { WorkbasketDistributionTargets } from 'app/shared/models/workbasket-distribution-targets';
import { WorkbasketService } from 'app/shared/services/workbasket/workbasket.service';
import { Page } from 'app/shared/models/page';
import { Actions, ofActionCompleted, Select, Store } from '@ngxs/store';
import { filter, take, takeUntil } from 'rxjs/operators';
import { NOTIFICATION_TYPES } from '../../../shared/models/notifications';
@ -22,7 +21,6 @@ import { WorkbasketSelectors } from '../../../shared/store/workbasket-store/work
import { ButtonAction } from '../../models/button-action';
import { Pair } from '../../../shared/models/pair';
import { WorkbasketQueryFilterParameter } from '../../../shared/models/workbasket-query-filter-parameter';
import { QueryPagingParameter } from '../../../shared/models/query-paging-parameter';
export enum Side {
AVAILABLE,
@ -41,26 +39,19 @@ export class WorkbasketDistributionTargetsComponent implements OnInit, OnDestroy
sideBySide = true;
displayingDistributionTargetsPicker = true;
distributionTargetsSelectedResource: WorkbasketDistributionTargets;
availableDistributionTargets: WorkbasketSummary[] = [];
distributionTargetsClone: WorkbasketSummary[];
distributionTargetsLeft: WorkbasketSummary[] = [];
distributionTargetsSelected: WorkbasketSummary[];
distributionTargetsSelectedClone: WorkbasketSummary[];
loadingItems = false;
side = Side;
private initialized = false;
currentPage: Page;
pageParameter: QueryPagingParameter = {
page: 1,
'page-size': 9
};
cards: number;
selectAllLeft = false;
selectAllRight = false;
availableDistributionTargets: WorkbasketSummary[] = [];
availableDistributionTargetsUndoClone: WorkbasketSummary[];
availableDistributionTargetsFilterClone: WorkbasketSummary[];
selectedDistributionTargets: WorkbasketSummary[];
selectedDistributionTargetsUndoClone: WorkbasketSummary[];
selectedDistributionTargetsFilterClone: WorkbasketSummary[];
selectedDistributionTargetsResource: WorkbasketDistributionTargets;
@Select(WorkbasketSelectors.workbasketDistributionTargets)
workbasketDistributionTargets$: Observable<WorkbasketDistributionTargets>;
@ -88,7 +79,10 @@ export class WorkbasketDistributionTargetsComponent implements OnInit, OnDestroy
*/
ngOnInit() {
this.selectedWorkbasket$
.pipe(filter((selectedWorkbasket) => typeof selectedWorkbasket !== 'undefined'))
.pipe(
filter((selectedWorkbasket) => typeof selectedWorkbasket !== 'undefined'),
takeUntil(this.destroy$)
)
.subscribe((selectedWorkbasket) => {
this.workbasket = selectedWorkbasket;
});
@ -98,20 +92,23 @@ export class WorkbasketDistributionTargetsComponent implements OnInit, OnDestroy
this.store.dispatch(new GetAvailableDistributionTargets());
}
this.availableDistributionTargets$
.pipe(takeUntil(this.destroy$))
.pipe(filter((availableDistributionTargets) => typeof availableDistributionTargets !== 'undefined'))
.subscribe((availableDistributionTargets) => {
this.availableDistributionTargets = availableDistributionTargets.map((wb) => ({ ...wb }));
});
this.workbasketDistributionTargets$.subscribe((workbasketDistributionTargets) => {
this.workbasketDistributionTargets$.pipe(takeUntil(this.destroy$)).subscribe((workbasketDistributionTargets) => {
if (typeof workbasketDistributionTargets !== 'undefined') {
this.distributionTargetsSelectedResource = { ...workbasketDistributionTargets };
this.distributionTargetsSelected = this.distributionTargetsSelectedResource.distributionTargets;
this.distributionTargetsSelectedClone = { ...this.distributionTargetsSelected };
this.pageParameter.page = 1;
this.getWorkbaskets();
this.selectedDistributionTargetsResource = { ...workbasketDistributionTargets };
this.selectedDistributionTargets = [];
workbasketDistributionTargets.distributionTargets.forEach((distributionTarget) => {
const target = {};
Object.keys(distributionTarget).forEach((key) => {
target[key] = distributionTarget[key];
});
this.selectedDistributionTargets.push(target);
});
this.selectedDistributionTargetsFilterClone = [...this.selectedDistributionTargets];
this.selectedDistributionTargetsUndoClone = [...this.selectedDistributionTargets];
this.getAvailableDistributionTargets();
}
});
@ -123,7 +120,7 @@ export class WorkbasketDistributionTargetsComponent implements OnInit, OnDestroy
// saving workbasket distributions targets when workbasket was copied or created
this.ngxsActions$.pipe(ofActionCompleted(SaveNewWorkbasket), takeUntil(this.destroy$)).subscribe(() => {
this.selectedWorkbasket$.pipe(take(1)).subscribe((workbasket) => {
this.distributionTargetsSelectedResource._links = {
this.selectedDistributionTargetsResource._links = {
self: { href: workbasket._links.distributionTargets.href }
};
this.onSave();
@ -144,13 +141,38 @@ export class WorkbasketDistributionTargetsComponent implements OnInit, OnDestroy
});
}
onScroll() {
if (this.currentPage && this.currentPage.totalPages > this.pageParameter.page) {
this.loadingItems = true;
this.getNextPage();
ngOnChanges(changes: SimpleChanges) {
if (changes.workbasket.currentValue !== changes.workbasket.previousValue) {
this.getAvailableDistributionTargets();
}
}
filterWorkbasketsByWorkbasketIDs(workbaskets: WorkbasketSummary[], IDs: WorkbasketSummary[]): WorkbasketSummary[] {
const workbasketIds: string[] = IDs.map((workbasket) => workbasket.workbasketId);
return workbaskets.filter((workbasket) => !workbasketIds.includes(workbasket.workbasketId));
}
getAvailableDistributionTargets() {
this.availableDistributionTargets$
.pipe(
take(1),
filter((availableDistributionTargets) => typeof availableDistributionTargets !== 'undefined')
)
.subscribe((availableDistributionTargets) => {
this.availableDistributionTargets = availableDistributionTargets.map((wb) => ({ ...wb }));
if (this.selectedDistributionTargets && this.selectedDistributionTargets.length !== 0) {
this.availableDistributionTargets = this.filterWorkbasketsByWorkbasketIDs(
this.availableDistributionTargets,
this.selectedDistributionTargets
);
}
this.availableDistributionTargetsUndoClone = [...this.availableDistributionTargets];
this.availableDistributionTargetsFilterClone = [...this.availableDistributionTargets];
});
}
changeToolbarState(state: boolean) {
this.toolbarState = state;
}
@ -159,56 +181,42 @@ export class WorkbasketDistributionTargetsComponent implements OnInit, OnDestroy
this.displayingDistributionTargetsPicker = !this.displayingDistributionTargetsPicker;
}
getWorkbaskets(side?: Side) {
if (this.distributionTargetsSelected && !this.initialized) {
this.initialized = true;
this.pageParameter['page-size'] = this.cards + this.distributionTargetsSelected.length;
}
this.workbasketService
.getWorkBasketsSummary(true, undefined, undefined, this.pageParameter)
.pipe(takeUntil(this.destroy$))
.subscribe((distributionTargetsAvailable: WorkbasketSummaryRepresentation) => {
if (this.pageParameter === 1) {
this.availableDistributionTargets = [];
this.currentPage = distributionTargetsAvailable.page;
}
if (side === Side.AVAILABLE) {
this.availableDistributionTargets.push(...distributionTargetsAvailable.workbaskets);
} else if (side === Side.SELECTED) {
this.distributionTargetsLeft = Object.assign([], distributionTargetsAvailable.workbaskets);
} else {
this.availableDistributionTargets.push(...distributionTargetsAvailable.workbaskets);
this.distributionTargetsLeft = Object.assign([], distributionTargetsAvailable.workbaskets);
this.distributionTargetsClone = Object.assign([], distributionTargetsAvailable.workbaskets);
}
});
}
getNextPage(side?: Side) {
this.pageParameter.page += 1;
this.getWorkbaskets(side);
}
// TODO:
// an own filter would save a lot of work here because the workbasketService filter
// returns all available distribution targets and must be filtered again
performFilter({ left: side, right: filter }: Pair<Side, WorkbasketQueryFilterParameter>) {
this.workbasketService
.getWorkBasketsSummary(true, filter)
.pipe(takeUntil(this.destroy$))
.subscribe((distributionTargetsAvailable: WorkbasketSummaryRepresentation) => {
this.fillDistributionTargets(side, []);
const isFilterEmpty =
filter['name-like'].length === 0 &&
filter['key-like'].length === 0 &&
filter['description-like'].length === 0 &&
filter['owner-like'].length === 0 &&
filter['type'].length === 0;
if (this.pageParameter === 1) {
this.availableDistributionTargets = [];
this.currentPage = distributionTargetsAvailable.page;
}
// filter available side
if (side === Side.AVAILABLE) {
this.availableDistributionTargets.push(...distributionTargetsAvailable.workbaskets);
} else if (side === Side.SELECTED) {
this.distributionTargetsLeft = Object.assign([], distributionTargetsAvailable.workbaskets);
} else {
this.availableDistributionTargets.push(...distributionTargetsAvailable.workbaskets);
this.distributionTargetsLeft = Object.assign([], distributionTargetsAvailable.workbaskets);
this.distributionTargetsClone = Object.assign([], distributionTargetsAvailable.workbaskets);
if (isFilterEmpty) {
this.availableDistributionTargets = this.availableDistributionTargetsFilterClone;
} else {
this.availableDistributionTargets = this.filterWorkbasketsByWorkbasketIDs(
distributionTargetsAvailable.workbaskets,
this.selectedDistributionTargetsFilterClone
);
}
}
// filter selected side
else if (side === Side.SELECTED) {
if (isFilterEmpty) {
this.selectedDistributionTargets = this.selectedDistributionTargetsFilterClone;
} else {
const ids = distributionTargetsAvailable.workbaskets.map((workbasket) => workbasket.workbasketId);
this.selectedDistributionTargets = this.selectedDistributionTargetsFilterClone.filter((workbasket) =>
ids.includes(workbasket.workbasketId)
);
}
}
});
}
@ -216,7 +224,7 @@ export class WorkbasketDistributionTargetsComponent implements OnInit, OnDestroy
onSave() {
this.store.dispatch(
new UpdateWorkbasketDistributionTargets(
this.distributionTargetsSelectedResource._links.self.href,
this.selectedDistributionTargetsResource._links.self.href,
this.getSelectedIds()
)
);
@ -224,44 +232,55 @@ export class WorkbasketDistributionTargetsComponent implements OnInit, OnDestroy
}
moveDistributionTargets(side: number) {
// get all workbaskets without applied filter and without overwriting the selected property
this.selectedDistributionTargets = this.selectedDistributionTargets.concat(
this.filterWorkbasketsByWorkbasketIDs(
this.selectedDistributionTargetsFilterClone,
this.selectedDistributionTargets
)
);
this.availableDistributionTargets = this.availableDistributionTargets.concat(
this.filterWorkbasketsByWorkbasketIDs(
this.availableDistributionTargetsFilterClone,
this.availableDistributionTargets
)
);
if (side === Side.AVAILABLE) {
const itemsLeft = this.availableDistributionTargets.length;
const itemsRight = this.distributionTargetsLeft.length;
// moving available items to selected side
const itemsSelected = this.getSelectedItems(this.availableDistributionTargets);
this.distributionTargetsSelected = [...this.distributionTargetsSelected, ...itemsSelected];
this.distributionTargetsLeft = this.distributionTargetsLeft.concat(itemsSelected);
if (
itemsLeft - itemsSelected.length <= this.pageParameter['page-size'] &&
itemsLeft + itemsRight < this.currentPage.totalElements
) {
this.getNextPage(side);
}
this.unselectItems(this.distributionTargetsSelected);
this.selectedDistributionTargets = this.selectedDistributionTargets.concat(itemsSelected);
this.availableDistributionTargets = this.removeSelectedItems(this.availableDistributionTargets, itemsSelected);
this.unselectItems(itemsSelected);
} else {
const itemsSelected = this.getSelectedItems(this.distributionTargetsLeft);
this.distributionTargetsSelected = this.removeSelectedItems(this.distributionTargetsSelected, itemsSelected);
this.distributionTargetsLeft = this.removeSelectedItems(this.distributionTargetsLeft, itemsSelected);
// moving selected items to available side
const itemsSelected = this.getSelectedItems(this.selectedDistributionTargets);
this.selectedDistributionTargets = this.removeSelectedItems(this.selectedDistributionTargets, itemsSelected);
this.availableDistributionTargets = this.availableDistributionTargets.concat(itemsSelected);
this.unselectItems(itemsSelected);
}
this.selectedDistributionTargetsFilterClone = this.selectedDistributionTargets;
this.availableDistributionTargetsFilterClone = this.availableDistributionTargets;
this.selectAllRight = true;
this.selectAllLeft = true;
}
onClear() {
this.notificationsService.showToast(NOTIFICATION_TYPES.INFO_ALERT);
this.availableDistributionTargets = Object.assign([], this.distributionTargetsClone);
this.distributionTargetsLeft = Object.assign([], this.distributionTargetsSelectedClone);
this.distributionTargetsSelected = Object.assign([], this.distributionTargetsSelectedClone);
}
fillDistributionTargets(side: Side, workbaskets: WorkbasketSummary[]) {
this.availableDistributionTargets = side === Side.AVAILABLE ? workbaskets : this.availableDistributionTargets;
this.distributionTargetsLeft = side === Side.SELECTED ? workbaskets : this.distributionTargetsLeft;
this.availableDistributionTargets = Object.assign([], this.availableDistributionTargetsUndoClone);
this.availableDistributionTargetsFilterClone = Object.assign([], this.availableDistributionTargetsUndoClone);
this.selectedDistributionTargets = Object.assign([], this.selectedDistributionTargetsUndoClone);
this.selectedDistributionTargetsFilterClone = Object.assign([], this.selectedDistributionTargetsUndoClone);
}
getSelectedItems(originList: any): any[] {
return originList.filter((item: any) => item.selected === true);
}
getSelectedIds(): string[] {
return this.selectedDistributionTargets.map((distributionTarget) => distributionTarget.workbasketId);
}
unselectItems(originList: any[]): any[] {
return originList
.filter((item) => item.selected)
@ -280,10 +299,6 @@ export class WorkbasketDistributionTargetsComponent implements OnInit, OnDestroy
return copyList;
}
getSelectedIds(): string[] {
return this.distributionTargetsSelected.map((distributionTarget) => distributionTarget.workbasketId);
}
toggleSideBySideView() {
this.sideBySide = !this.sideBySide;
this.displayingDistributionTargetsPicker = true; //always display picker when toggle from side-by-side to single

View File

@ -1,22 +0,0 @@
import { Pipe, PipeTransform } from '@angular/core';
import { WorkbasketSummary } from '../models/workbasket-summary';
import { Side } from '../../administration/components/workbasket-distribution-targets/workbasket-distribution-targets.component';
@Pipe({ name: 'selectWorkbaskets' })
export class SelectWorkBasketPipe implements PipeTransform {
transform(
allWorkbaskets: WorkbasketSummary[],
selectedWorkbaskets: WorkbasketSummary[],
side: Side
): WorkbasketSummary[] {
if (!allWorkbaskets || !selectedWorkbaskets) {
return [];
}
if (side === Side.SELECTED) {
return selectedWorkbaskets;
}
const selectedWorkbasketIds: string[] = selectedWorkbaskets.map((wb) => wb.workbasketId);
const isNotASelectedWorkbasket = (wb: WorkbasketSummary) => !selectedWorkbasketIds.includes(wb.workbasketId);
return allWorkbaskets.filter(isNotASelectedWorkbasket);
}
}

View File

@ -37,7 +37,6 @@ import { DropdownComponent } from './components/dropdown/dropdown.component';
*/
import { MapValuesPipe } from './pipes/map-values.pipe';
import { RemoveNoneTypePipe } from './pipes/remove-empty-type.pipe';
import { SelectWorkBasketPipe } from './pipes/select-workbaskets.pipe';
import { SpreadNumberPipe } from './pipes/spread-number.pipe';
import { OrderBy } from './pipes/order-by.pipe';
import { MapToIterable } from './pipes/map-to-iterable.pipe';
@ -87,7 +86,6 @@ const DECLARATIONS = [
TypeAheadComponent,
MapValuesPipe,
RemoveNoneTypePipe,
SelectWorkBasketPipe,
SpreadNumberPipe,
DateTimeZonePipe,
NumberToArray,