LP1904036 Patron holds uncancel option; display title
authorBill Erickson <berickxx@gmail.com>
Mon, 23 Aug 2021 15:06:32 +0000 (11:06 -0400)
committerGalen Charlton <gmc@equinoxOLI.org>
Fri, 28 Oct 2022 00:13:36 +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/circ/patron/holds.component.html
Open-ILS/src/eg2/src/app/staff/share/holds/grid.component.html
Open-ILS/src/eg2/src/app/staff/share/holds/grid.component.ts

index bd3f245..758cb78 100644 (file)
@@ -9,6 +9,7 @@
         printTemplate="holds_for_patron"
         persistKey="circ.patron.holds"
         (placeHoldRequested)="newHold()"
+        [patronFocused]="true"
         [noLoadProgress]="true"
         [showPlaceHoldButton]="true"
         [hidePickupLibFilter]="true"
@@ -23,6 +24,7 @@
       <eg-holds-grid 
         printTemplate="holds_for_patron"
         persistKey="circ.patron.holds"
+        [patronFocused]="true"
         [noLoadProgress]="true"
         [hidePickupLibFilter]="true"
         [showRecentlyCanceled]="true"
index eecc626..9f8ea0b 100644 (file)
@@ -9,6 +9,11 @@
 <eg-hold-retarget-dialog #retargetDialog></eg-hold-retarget-dialog>
 <eg-hold-cancel-dialog #cancelDialog></eg-hold-cancel-dialog>
 <eg-hold-manage-dialog #manageDialog></eg-hold-manage-dialog>
+<eg-confirm-dialog #uncancelDialog
+  i18n-dialogTitle i18n-dialogBody
+  i18n-dialogTitle="Un-Cancel Holds"
+  dialogBody="Un-Cancel {{uncancelHoldCount}} hold(s)?"
+></eg-confirm-dialog>
 
 <ng-template #statusTemplate let-hold="row">
   <ng-container [ngSwitch]="hold.hold_status">
         i18n-label label="Show Last Few Circulations" group="Item" i18n-group
         (onClick)="showRecentCircs($event)"></eg-grid-toolbar-action>
 
-      <eg-grid-toolbar-action
+      <eg-grid-toolbar-action *ngIf="!patronFocused"
         i18n-label label="Retrieve Patron" group="Patron" i18n-group
         (onClick)="showPatron($event)">
       </eg-grid-toolbar-action>
         i18n-group group="Hold" i18n-label label="Find Another Target"
         (onClick)="showRetargetDialog($event)"></eg-grid-toolbar-action>
 
-      <eg-grid-toolbar-action
+      <eg-grid-toolbar-action *ngIf="!showRecentlyCanceled"
         i18-group group="Hold" i18n-label label="Cancel Hold"
-        (onClick)="showCancelDialog($event)"></eg-grid-toolbar-action>
+        (onClick)="showUncancelDialog($event)"></eg-grid-toolbar-action>
+
+      <eg-grid-toolbar-action *ngIf="showRecentlyCanceled"
+        i18n-label label="Un-Cancel Hold(s)" group="Hold" i18n-group
+        (onClick)="showUncancelDialog($event)">
+      </eg-grid-toolbar-action>
 
       <eg-grid-toolbar-action
         i18-group group="Hold" i18n-label label="Print Holds"
index 65cad22..8a3bad3 100644 (file)
@@ -1,6 +1,7 @@
 import {Component, OnInit, Input, Output, EventEmitter, ViewChild} from '@angular/core';
 import {Location} from '@angular/common';
-import {Observable, Observer, of} from 'rxjs';
+import {Observable, Observer, of, from} from 'rxjs';
+import {concatMap} from 'rxjs/operators';
 import {IdlObject} from '@eg/core/idl.service';
 import {NetService} from '@eg/core/net.service';
 import {OrgService} from '@eg/core/org.service';
@@ -10,6 +11,7 @@ import {ServerStoreService} from '@eg/core/server-store.service';
 import {GridDataSource, GridColumn, GridCellTextGenerator} from '@eg/share/grid/grid';
 import {GridComponent} from '@eg/share/grid/grid.component';
 import {ProgressDialogComponent} from '@eg/share/dialog/progress.component';
+import {ConfirmDialogComponent} from '@eg/share/dialog/confirm.component';
 import {MarkDamagedDialogComponent
     } from '@eg/staff/share/holdings/mark-damaged-dialog.component';
 import {MarkMissingDialogComponent
@@ -74,6 +76,10 @@ export class HoldsGridComponent implements OnInit {
     // has it's own generic embedded 'loading' progress indicator.
     @Input() noLoadProgress = false;
 
+    // Some default columns and actions do or don't make sense when
+    // displaying holds for a specific patron vs. e.g. a specific title.
+    @Input() patronFocused = false;
+
     mode: 'list' | 'detail' | 'manage' = 'list';
     initDone = false;
     holdsCount: number;
@@ -83,6 +89,7 @@ export class HoldsGridComponent implements OnInit {
     detailHold: any;
     editHolds: number[];
     transferTarget: number;
+    uncancelHoldCount: number;
 
     @ViewChild('holdsGrid', { static: false }) private holdsGrid: GridComponent;
     @ViewChild('progressDialog', { static: true })
@@ -101,6 +108,7 @@ export class HoldsGridComponent implements OnInit {
         private cancelDialog: HoldCancelDialogComponent;
     @ViewChild('manageDialog', { static: true })
         private manageDialog: HoldManageDialogComponent;
+    @ViewChild('uncancelDialog') private uncancelDialog: ConfirmDialogComponent;
 
     // Bib record ID.
     _recordId: number;
@@ -619,6 +627,36 @@ export class HoldsGridComponent implements OnInit {
         }
     }
 
+    showUncancelDialog(rows: any[]) {
+        const holdIds = rows.map(r => r.id).filter(id => Boolean(id));
+        if (holdIds.length === 0) { return; }
+        this.uncancelHoldCount = holdIds.length;
+
+        this.uncancelDialog.open().subscribe(confirmed => {
+            if (!confirmed) { return; }
+            this.progressDialog.open();
+
+            from(holdIds).pipe(concatMap(holdId => {
+                return this.net.request(
+                    'open-ils.circ',
+                    'open-ils.circ.hold.uncancel',
+                    this.auth.token(), holdId
+                )
+            })).subscribe(
+                resp => {
+                    if (Number(resp) !== 1) {
+                        console.error('Failed uncanceling hold', resp);
+                    }
+                },
+                null,
+                () => {
+                    this.progressDialog.close();
+                    this.holdsGrid.reload();
+                }
+            );
+        });
+    }
+
     printHolds() {
         // Request a page with no limit to get all of the wide holds for
         // printing.  Call requestPage() directly instead of grid.reload()