From 09a84edb090893e3717df93988f8f537a8176656 Mon Sep 17 00:00:00 2001 From: Kristof De Langhe <kristof.delanghe@atmire.com> Date: Thu, 27 Sep 2018 11:09:36 +0200 Subject: [PATCH] 55693: Working store interaction for selecting items --- resources/i18n/en.json | 3 +- .../collection-item-mapper.component.html | 2 +- .../collection-item-mapper.component.ts | 4 +++ .../item-select/item-select.component.html | 3 +- .../item-select/item-select.component.ts | 15 ++++++++-- .../shared/item-select/item-select.reducer.ts | 2 +- .../shared/item-select/item-select.service.ts | 28 +++++++++++++++---- 7 files changed, 45 insertions(+), 12 deletions(-) diff --git a/resources/i18n/en.json b/resources/i18n/en.json index 63ee598199..948f538e9a 100644 --- a/resources/i18n/en.json +++ b/resources/i18n/en.json @@ -59,7 +59,8 @@ "collection": "Collection", "author": "Author", "title": "Title" - } + }, + "confirm": "Confirm selected" } }, "nav": { diff --git a/src/app/+collection-page/collection-item-mapper/collection-item-mapper.component.html b/src/app/+collection-page/collection-item-mapper/collection-item-mapper.component.html index f8d770423b..d201ce0ad6 100644 --- a/src/app/+collection-page/collection-item-mapper/collection-item-mapper.component.html +++ b/src/app/+collection-page/collection-item-mapper/collection-item-mapper.component.html @@ -30,7 +30,7 @@ <ngb-tab title="{{'collection.item-mapper.tabs.map' | translate}}"> <ng-template ngbTabContent> <div class="mt-2"> - <ds-item-select class="mt-2" [itemsRD$]="mappingItemsRD$" [paginationOptions]="(searchOptions$ | async)?.pagination"></ds-item-select> + <ds-item-select class="mt-2" [itemsRD$]="mappingItemsRD$" [paginationOptions]="(searchOptions$ | async)?.pagination" (confirm)="mapItems($event)"></ds-item-select> </div> </ng-template> </ngb-tab> diff --git a/src/app/+collection-page/collection-item-mapper/collection-item-mapper.component.ts b/src/app/+collection-page/collection-item-mapper/collection-item-mapper.component.ts index 622bd14547..f796abc54a 100644 --- a/src/app/+collection-page/collection-item-mapper/collection-item-mapper.component.ts +++ b/src/app/+collection-page/collection-item-mapper/collection-item-mapper.component.ts @@ -70,6 +70,10 @@ export class CollectionItemMapperComponent implements OnInit { ); } + mapItems(ids: string[]) { + console.log(ids); + } + getCurrentUrl(): string { const urlTree = this.router.parseUrl(this.router.url); const g: UrlSegmentGroup = urlTree.root.children[PRIMARY_OUTLET]; diff --git a/src/app/shared/item-select/item-select.component.html b/src/app/shared/item-select/item-select.component.html index c20e2cd6c1..4047884bc4 100644 --- a/src/app/shared/item-select/item-select.component.html +++ b/src/app/shared/item-select/item-select.component.html @@ -17,7 +17,7 @@ </thead> <tbody> <tr *ngFor="let item of (itemsRD$ | async)?.payload?.page"> - <td><input [ngModel]="getSelected(item.id) | async" (change)="switch(item.id)" type="checkbox"></td> + <td><input [ngModel]="getSelected(item.id) | async" (change)="switch(item.id)" type="checkbox" name="{{item.id}}"></td> <td><a [routerLink]="['/items', item.id]">{{(item.owningCollection | async)?.payload?.name}}</a></td> <td><a *ngIf="item.filterMetadata(['dc.contributor.author', 'dc.creator', 'dc.contributor.*']).length > 0" [routerLink]="['/items', item.id]">{{item.filterMetadata(['dc.contributor.author', 'dc.creator', 'dc.contributor.*'])[0].value}}</a></td> <td><a [routerLink]="['/items', item.id]">{{item.findMetadata("dc.title")}}</a></td> @@ -26,3 +26,4 @@ </table> </div> </ds-pagination> +<button class="btn btn-outline-secondary" (click)="confirmSelected()">{{'item.select.confirm' | translate}}</button> diff --git a/src/app/shared/item-select/item-select.component.ts b/src/app/shared/item-select/item-select.component.ts index e24ce1c4fa..93128aa1d5 100644 --- a/src/app/shared/item-select/item-select.component.ts +++ b/src/app/shared/item-select/item-select.component.ts @@ -1,4 +1,4 @@ -import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core'; import { ItemDataService } from '../../core/data/item-data.service'; import { PaginatedList } from '../../core/data/paginated-list'; import { RemoteData } from '../../core/data/remote-data'; @@ -21,13 +21,16 @@ export class ItemSelectComponent implements OnInit { @Input() paginationOptions: PaginationComponentOptions; - checked: boolean[] = []; + @Output() + confirm: EventEmitter<string[]> = new EventEmitter<string[]>(); + + selectedIds$: Observable<string[]>; constructor(private itemSelectService: ItemSelectService) { } ngOnInit(): void { - this.itemsRD$.subscribe((value) => console.log(value)); + this.selectedIds$ = this.itemSelectService.getAllSelected(); } switch(id: string) { @@ -38,4 +41,10 @@ export class ItemSelectComponent implements OnInit { return this.itemSelectService.getSelected(id); } + confirmSelected() { + this.selectedIds$.subscribe((ids: string[]) => { + this.confirm.emit(ids); + }); + } + } diff --git a/src/app/shared/item-select/item-select.reducer.ts b/src/app/shared/item-select/item-select.reducer.ts index 1ea443850b..6306adf0c4 100644 --- a/src/app/shared/item-select/item-select.reducer.ts +++ b/src/app/shared/item-select/item-select.reducer.ts @@ -68,7 +68,7 @@ export function itemSelectionReducer(state = initialState, action: ItemSelection case ItemSelectionActionTypes.SWITCH: { return Object.assign({}, state, { [action.id]: { - checked: !state.checked + checked: (isEmpty(state) || isEmpty(state[action.id])) ? true : !state[action.id].checked } }); } diff --git a/src/app/shared/item-select/item-select.service.ts b/src/app/shared/item-select/item-select.service.ts index 3ba9f9a579..bf4c7ba239 100644 --- a/src/app/shared/item-select/item-select.service.ts +++ b/src/app/shared/item-select/item-select.service.ts @@ -9,8 +9,11 @@ import { } from './item-select.actions'; import { Observable } from 'rxjs/Observable'; import { hasValue } from '../empty.util'; +import { map } from 'rxjs/operators'; +import { AppState } from '../../app.reducer'; -const selectionStateSelector = (state: ItemSelectionsState) => state.selectionItem; +const selectionStateSelector = (state: ItemSelectionsState) => state.itemSelection; +const itemSelectionsStateSelector = (state: AppState) => state.itemSelection; /** * Service that takes care of selecting and deselecting items @@ -18,7 +21,10 @@ const selectionStateSelector = (state: ItemSelectionsState) => state.selectionIt @Injectable() export class ItemSelectService { - constructor(private store: Store<ItemSelectionsState>) { + constructor( + private store: Store<ItemSelectionsState>, + private appStore: Store<AppState> + ) { } /** @@ -27,14 +33,26 @@ export class ItemSelectService { * @returns {Observable<boolean>} Emits the current selection state of the given item, if it's unavailable, return false */ getSelected(id: string): Observable<boolean> { - return this.store.select(selectionByIdSelector(id)) - .map((object: ItemSelectionState) => { + return this.store.select(selectionByIdSelector(id)).pipe( + map((object: ItemSelectionState) => { if (object) { return object.checked; } else { return false; } - }); + }) + ); + } + + /** + * Request the current selection of a given item + * @param {string} id The UUID of the item + * @returns {Observable<boolean>} Emits the current selection state of the given item, if it's unavailable, return false + */ + getAllSelected(): Observable<string[]> { + return this.appStore.select(itemSelectionsStateSelector).pipe( + map((state: ItemSelectionsState) => Object.keys(state).filter((key) => state[key].checked)) + ); } /** -- GitLab