LP1904036 Mark items lost
authorBill Erickson <berickxx@gmail.com>
Thu, 25 Feb 2021 17:10:56 +0000 (12:10 -0500)
committerGalen Charlton <gmc@equinoxOLI.org>
Fri, 28 Oct 2022 00:13:24 +0000 (20:13 -0400)
Signed-off-by: Bill Erickson <berickxx@gmail.com>
Signed-off-by: Jane Sandberg <js7389@princeton.edu>
Signed-off-by: Galen Charlton <gmc@equinoxOLI.org>
Open-ILS/src/eg2/src/app/staff/share/circ/circ.service.ts
Open-ILS/src/eg2/src/app/staff/share/circ/grid.component.html
Open-ILS/src/eg2/src/app/staff/share/circ/grid.component.ts

index 3c513d0..027bfd6 100644 (file)
@@ -1,6 +1,6 @@
 import {Injectable} from '@angular/core';
-import {Observable, empty} from 'rxjs';
-import {map, mergeMap} from 'rxjs/operators';
+import {Observable, empty, from} from 'rxjs';
+import {map, concatMap, mergeMap} from 'rxjs/operators';
 import {IdlObject} from '@eg/core/idl.service';
 import {NetService} from '@eg/core/net.service';
 import {OrgService} from '@eg/core/org.service';
@@ -178,29 +178,14 @@ export class CircService {
         if (copyIds.length === 0) { return empty(); }
 
         if (!params) { params = {}; }
-        const ids = [].concat(copyIds); // clone
 
-        let observer;
-        const observable = new Observable<CheckinResult>(o => observer = o);
-
-        const checkinOne = (ids: number[]): Promise<CheckinResult> => {
-            if (ids.length === 0) {
-                observer.complete();
-                return Promise.resolve(null);
-            }
+        const source = from(copyIds);
 
+        return source.pipe(concatMap(id => {
             const cparams = Object.assign(params, {}); // clone
-            cparams.copy_id = ids.pop();
-
-            return this.checkin(cparams).then(result => {
-                observer.next(result);
-                return checkinOne(ids);
-            });
-        }
-
-        checkinOne(ids);
-
-        return observable;
+            cparams.copy_id = id;
+            return from(this.checkin(cparams));
+        }));
     }
 }
 
index 5317727..18b0ec6 100644 (file)
     group="Mark" i18n-group i18n-label label="Mark Item Missing"
     (onClick)="showMarkMissingDialog($event)"></eg-grid-toolbar-action>
 
-  <eg-grid-toolbar-action i18n-label label="Checkin" (onClick)="checkin($event)">
+  <eg-grid-toolbar-action
+    group="Mark" i18n-group i18n-label label="Mark Item Lost"
+    (onClick)="markLost($event)"></eg-grid-toolbar-action>
+
+  <!-- .subscribe() nudges the observable to run -->
+  <eg-grid-toolbar-action i18n-label label="Checkin" 
+    (onClick)="checkin($event).subscribe()">
   </eg-grid-toolbar-action>
 
   <eg-grid-column [index]="true" path="index" [hidden]="true"
index 43d1f1f..1b9ff06 100644 (file)
@@ -1,14 +1,16 @@
 import {Component, OnInit, Output, Input, ViewChild, EventEmitter} from '@angular/core';
 import {Router, ActivatedRoute, ParamMap} from '@angular/router';
 import {Observable, empty, of, from} from 'rxjs';
-import {map, tap, switchMap} from 'rxjs/operators';
+import {map, tap, switchMap, concatMap} from 'rxjs/operators';
 import {IdlObject} from '@eg/core/idl.service';
 import {OrgService} from '@eg/core/org.service';
 import {NetService} from '@eg/core/net.service';
+import {AuthService} from '@eg/core/auth.service';
 import {PcrudService} from '@eg/core/pcrud.service';
 import {CheckoutParams, CheckoutResult, CheckinParams, CheckinResult,
     CircService} from './circ.service';
 import {PromptDialogComponent} from '@eg/share/dialog/prompt.component';
+import {ProgressDialogComponent} from '@eg/share/dialog/progress.component';
 import {ConfirmDialogComponent} from '@eg/share/dialog/confirm.component';
 import {GridDataSource, GridColumn, GridCellTextGenerator,
     GridRowFlairEntry} from '@eg/share/grid/grid';
@@ -98,10 +100,13 @@ export class CircGridComponent implements OnInit {
         private markMissingDialog: MarkMissingDialogComponent;
     @ViewChild('itemsOutConfirm')
         private itemsOutConfirm: ConfirmDialogComponent;
+    @ViewChild('progressDialog')
+        private progressDialog: ProgressDialogComponent;
 
     constructor(
         private org: OrgService,
         private net: NetService,
+        private auth: AuthService,
         private pcrud: PcrudService,
         public circ: CircService,
         private audio: AudioService,
@@ -136,6 +141,12 @@ export class CircGridComponent implements OnInit {
         };
     }
 
+    // Ask the caller to update our data set.
+    emitReloadRequest() {
+        this.entries = null;
+        this.reloadRequested.emit();
+    }
+
     // Reload the grid without any data retrieval
     reloadGrid() {
         this.circGrid.reload();
@@ -254,6 +265,10 @@ export class CircGridComponent implements OnInit {
         return copies;
     }
 
+    getCircIds(rows: CircGridEntry[]): number[] {
+        return this.getCircs(rows).map(row => Number(row.id()));
+    }
+
     getCircs(rows: any): IdlObject[] {
         return rows.filter(r => r.circ).map(r => r.circ);
     }
@@ -342,7 +357,7 @@ export class CircGridComponent implements OnInit {
         this.itemsOutConfirm.open().subscribe(confirmed => {
             if (!confirmed) { return; }
 
-            this.checkin(rows, {noop: true}, true).then(_ => {
+            this.checkin(rows, {noop: true}, true).toPromise().then(_ => {
 
                 this.markMissingDialog.copyIds = copyIds;
                 this.markMissingDialog.open({}).subscribe(
@@ -356,16 +371,48 @@ export class CircGridComponent implements OnInit {
         });
     }
 
-    // TODO: progress dialog
+    openProgressDialog(rows: CircGridEntry[]): ProgressDialogComponent {
+        this.progressDialog.update({value: 0, max: rows.length});
+        this.progressDialog.open();
+        return this.progressDialog;
+    }
+
     // Same params will be used for each copy
-    checkin(rows: CircGridEntry[], params?: CheckinParams, noReload?: boolean): Promise<any> {
-        return this.circ.checkinBatch(this.getCopyIds(rows), params).toPromise()
-        .then(_ => { if (!noReload) { this.emitReloadRequest(); } });
+    checkin(rows: CircGridEntry[], params?:
+        CheckinParams, noReload?: boolean): Observable<CheckinResult> {
+
+        const dialog = this.openProgressDialog(rows);
+
+        return this.circ.checkinBatch(this.getCopyIds(rows), params)
+        .pipe(tap(
+            result => dialog.increment(),
+            err => null,
+            () => {
+                dialog.close();
+                if (!noReload) { this.emitReloadRequest(); }
+            }
+        ));
     }
 
-    emitReloadRequest() {
-        this.entries = null;
-        this.reloadRequested.emit();
+    //markLost(rows: CircGridEntry[]): Observable<any> {
+    markLost(rows: CircGridEntry[]) {
+        const dialog = this.openProgressDialog(rows);
+        const barcodes = this.getCopies(rows).map(c => c.barcode());
+
+        from(barcodes).pipe(concatMap(barcode => {
+            return this.net.request(
+                'open-ils.circ',
+                'open-ils.circ.circulation.set_lost',
+                this.auth.token(), {barcode: barcode}
+            );
+        })).subscribe(
+            result => dialog.increment(),
+            err => console.error(err),
+            () => {
+                dialog.close();
+                this.emitReloadRequest();
+            }
+        );
     }
 }