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