LP1904036 Patron ui checkout tab
authorBill Erickson <berickxx@gmail.com>
Fri, 5 Feb 2021 21:26:03 +0000 (16:26 -0500)
committerGalen Charlton <gmc@equinoxOLI.org>
Fri, 28 Oct 2022 00:13:23 +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/checkout.component.html
Open-ILS/src/eg2/src/app/staff/circ/patron/checkout.component.ts
Open-ILS/src/eg2/src/app/staff/share/circ/circ.service.ts

index dea9023..c856da3 100644 (file)
@@ -1,4 +1,6 @@
 
+<eg-progress-dialog #progressDialog></eg-progress-dialog>
+
 <eg-prompt-dialog #nonCatCount
   promptType="number"
   i18n-dialogTitle dialogTitle="Non-Cat Checkout"
@@ -29,7 +31,7 @@
         </div>
         <input type="text" class="form-control" id="barcode-input"
           [placeholder]="checkoutNoncat ? '' : 'Barcode...'" i18n-placeholder
-          [disabled]="checkoutNoncat != null"
+          [(ngModel)]="checkoutBarcode" [disabled]="checkoutNoncat != null"
           i18n-aria-label aria-label="Barcode Input"/>
         <div class="input-group-append">
           <button class="btn btn-outline-dark" (click)="checkout()" i18n>Submit</button>
     </div>
   </div>
 </div>
+
+<ng-template #titleTemplate let-r="row">
+  <ng-container *ngIf="r.record">
+    <a routerLink="/staff/catalog/record/{{r.record.id()}}">{{r.title}}</a>
+  </ng-container>
+  <ng-container *ngIf="!r.record">{{r.title}}</ng-container>
+</ng-template>
+
+<div class="row">
+  <div class="col-lg-12">
+    <eg-grid #checkoutsGrid [dataSource]="gridDataSource" [sortable]="true"
+      [useLocalSort]="true" [cellTextGenerator]="cellTextGenerator"
+      persistKey="circ.patron.checkout">
+      <eg-grid-column path="index" [index]="true" 
+        label="Row Index" i18n-label [hidden]="true"></eg-grid-column>
+      <eg-grid-column path="circ.id" label="Circ ID" i18n-label></eg-grid-column>
+      <eg-grid-column path="title" label="Title" i18n-label 
+        [cellTemplate]="titleTemplate"></eg-grid-column>
+    </eg-grid>
+  </div>
+</div>
+
+
+
+
index a372f14..9a278a2 100644 (file)
@@ -1,6 +1,6 @@
 import {Component, OnInit, AfterViewInit, Input, ViewChild} from '@angular/core';
 import {Router, ActivatedRoute, ParamMap} from '@angular/router';
-import {Observable, empty, of} from 'rxjs';
+import {Observable, empty, of, from} from 'rxjs';
 import {tap, switchMap} from 'rxjs/operators';
 import {NgbNav, NgbNavChangeEvent} from '@ng-bootstrap/ng-bootstrap';
 import {IdlObject} from '@eg/core/idl.service';
@@ -10,6 +10,15 @@ import {PatronService} from '@eg/staff/share/patron/patron.service';
 import {PatronManagerService} from './patron.service';
 import {CheckoutParams, CheckoutResult, CircService} from '@eg/staff/share/circ/circ.service';
 import {PromptDialogComponent} from '@eg/share/dialog/prompt.component';
+import {GridDataSource, GridColumn, GridCellTextGenerator} from '@eg/share/grid/grid';
+import {GridComponent} from '@eg/share/grid/grid.component';
+import {Pager} from '@eg/share/util/pager';
+
+interface CircGridEntry {
+    title?: string;
+    circ?: IdlObject;
+    copyAlertCount: number;
+}
 
 @Component({
   templateUrl: 'checkout.component.html',
@@ -19,8 +28,13 @@ export class CheckoutComponent implements OnInit {
 
     maxNoncats = 99; // Matches AngJS version
     checkoutNoncat: IdlObject = null;
+    checkoutBarcode = '';
+    checkouts: CircGridEntry[] = [];
+    gridDataSource: GridDataSource = new GridDataSource();
+    cellTextGenerator: GridCellTextGenerator;
 
     @ViewChild('nonCatCount') nonCatCount: PromptDialogComponent;
+    @ViewChild('checkoutsGrid') checkoutsGrid: GridComponent;
 
     constructor(
         private org: OrgService,
@@ -32,9 +46,21 @@ export class CheckoutComponent implements OnInit {
 
     ngOnInit() {
         this.circ.getNonCatTypes();
+
+        this.gridDataSource.getRows = (pager: Pager, sort: any[]) => {
+            return from(this.checkouts);
+        };
+
+        this.cellTextGenerator = {
+            title: row => row.title
+        };
     }
 
     ngAfterViewInit() {
+        this.focusInput();
+    }
+
+    focusInput() {
         const input = document.getElementById('barcode-input');
         if (input) { input.focus(); }
     }
@@ -54,27 +80,55 @@ export class CheckoutComponent implements OnInit {
                 params.noncat_type = this.checkoutNoncat.id();
                 return params;
             });
+        } else if (this.checkoutBarcode) {
+            params.copy_barcode = this.checkoutBarcode;
+            return Promise.resolve(params);
         }
 
-        return null;
+        return Promise.resolve(null);
     }
 
     checkout() {
         this.collectParams()
 
         .then((params: CheckoutParams) => {
-            if (!params) { return null; }
-            return this.circ.checkout(params);
+            if (params) {
+                return this.circ.checkout(params);
+            }
         })
 
         .then((result: CheckoutResult) => {
-            if (!result) { return null; }
-
-            // Reset the form
-            this.checkoutNoncat = null;
+            if (result) {
+                if (result.success) {
+                    this.gridifyResult(result);
+                    this.resetForm();
+                }
+            }
         });
     }
 
+    resetForm() {
+        this.checkoutBarcode = '';
+        this.checkoutNoncat = null;
+        this.focusInput();
+    }
+
+    gridifyResult(result: CheckoutResult) {
+        const entry: CircGridEntry = {
+            circ: result.circ,
+            copyAlertCount: 0 // TODO
+        };
+
+        if (this.checkoutNoncat) {
+            entry.title = this.checkoutNoncat.name();
+        } else if (result.record) {
+            entry.title = result.record.title();
+        }
+
+        this.checkouts.unshift(entry);
+        this.checkoutsGrid.reload();
+    }
+
     noncatPrompt(): Observable<number> {
         return this.nonCatCount.open()
         .pipe(switchMap(count => {
index f3ab34a..554b77d 100644 (file)
@@ -11,19 +11,28 @@ import {BibRecordService, BibRecordSummary} from '@eg/share/catalog/bib-record.s
 import {AudioService} from '@eg/share/util/audio.service';
 
 
+// API parameter options
 export interface CheckoutParams {
     patron_id: number;
+    copy_id?: number;
+    copy_barcode?: string;
     noncat?: boolean;
     noncat_type?: number;
     noncat_count?: number;
+    noop?: boolean;
 }
 
 export interface CheckoutResult {
+    index: number;
+    params: CheckoutParams,
+    success: boolean;
     circ?: IdlObject;
+    record?: IdlObject;
 }
 
 @Injectable()
 export class CircService {
+    static resultIndex = 0;
 
     nonCatTypes: IdlObject[] = null;
 
@@ -58,10 +67,12 @@ export class CircService {
             'open-ils.circ',
             'open-ils.circ.checkout.full',
             this.auth.token(), params
-        ).toPromise().then(result => this.processCheckoutResult(result))
+        ).toPromise().then(result => this.processCheckoutResult(params, result))
     }
 
-    processCheckoutResult(response: any): Promise<CheckoutResult> {
+    processCheckoutResult(
+        params: CheckoutParams, response: any): Promise<CheckoutResult> {
+
         console.debug('checkout resturned', response);
 
         if (Array.isArray(response)) { response = response[0]; }
@@ -75,6 +86,9 @@ export class CircService {
         }
 
         const result: CheckoutResult = {
+            index: CircService.resultIndex++,
+            params: params,
+            success: true,
             circ: payload.circ
         };