-<h4>Place Hold</h4>
+<h3 i18n>Place Hold</h3>
-<form class="form form-validated common-form striped-odd" autocomplete="off">
+<form class="form form-validated common-form striped-odd"
+ autocomplete="off" (keydown.enter)="$event.preventDefault()">
<div class="row">
<div class="col-lg-3">
<div class="form-check">
</div>
</div>
<div class="col-lg-3">
- <input type='text' class="form-control" name="patronBarcode"
- [disabled]="holdFor!='patron'" id='patron-barcode' [(ngModel)]="patronBarcode"/>
+ <div class="input-group">
+ <input type='text' class="form-control" name="userBarcode"
+ [disabled]="holdFor!='patron'" id='patron-barcode'
+ (keyup.enter)="userBarcodeChanged()"
+ [(ngModel)]="userBarcode" (change)="userBarcodeChanged()"/>
+ <div class="input-group-append">
+ <button class="btn btn-outline-dark"
+ (click)="userSearch()" i18n>Search</button>
+ </div>
+ </div>
</div>
- </div>
- <div class="row mt-2">
<div class="col-lg-3">
<div class="form-check">
<input class="form-check-input" type="radio"
name="holdFor" value="staff" [(ngModel)]="holdFor"/>
<label class="form-check-label" i18n>
- Place hold for this staff account:
+ Place hold for this staff account: {{requestor.usrname()}}
</label>
</div>
</div>
- <div class="col-lg-3">
- <span class="font-weight-bold">{{requestor.usrname()}}</span>
- </div>
</div>
<div class="row mt-2">
<div class="col-lg-3">
<div class="col-lg-3">
<div class="form-check">
<input class="form-check-input" type="checkbox" name="notifyEmail"
- [disabled]="!user.email()" [(ngModel)]="notifyEmail"/>
+ [disabled]="!user || !user.email()" [(ngModel)]="notifyEmail"/>
<label class="form-check-label" i18n>Notify by Email</label>
</div>
</div>
<span class="input-group-text" i18n>Email Address</span>
</div>
<input type="text" class="form-control" name="userEmail"
- [disabled]="true" value="{{user.email()}}"/>
+ [disabled]="true" value="{{user ? user.email() : ''}}"/>
</div>
</div>
</div>
</div>
</form>
+<h4 class="p-3" i18n>Placing Hold(s) On Records...</h4>
+
+<ng-container *ngFor="let recId of recordIds">
+ <div class="row mt-2 ml-2 mr-2">
+ <div class="col-lg-12">
+ <eg-bib-summary [recordId]="recId" [expand]="false"></eg-bib-summary>
+ </div>
+ </div>
+</ng-container>
+
import {Component, OnInit, Input, ViewChild, Renderer2} from '@angular/core';
import {Router, ActivatedRoute, ParamMap} from '@angular/router';
+import {EventService} from '@eg/core/event.service';
+import {NetService} from '@eg/core/net.service';
import {AuthService} from '@eg/core/auth.service';
import {PcrudService} from '@eg/core/pcrud.service';
import {IdlObject} from '@eg/core/idl.service';
import {CatalogSearchContext, CatalogSearchState} from '@eg/share/catalog/search-context';
import {CatalogService} from '@eg/share/catalog/catalog.service';
-import {BibRecordService, BibRecordSummary} from '@eg/share/catalog/bib-record.service';
import {StaffCatalogService} from '../catalog.service';
-import {BibSummaryComponent} from '@eg/staff/share/bib-summary/bib-summary.component';
@Component({
templateUrl: 'hold.component.html'
holdType: string;
holdTargets: number[];
user: IdlObject; //
+ userBarcode: string;
requestor: IdlObject;
holdFor: string;
pickupLib: number;
phoneValue: string;
suspend: boolean;
activeDate: string;
+ recordIds: number[];
+
+ barcodeInFlight: string;
constructor(
private router: Router,
private route: ActivatedRoute,
private renderer: Renderer2,
+ private evt: EventService,
+ private net: NetService,
private auth: AuthService,
private pcrud: PcrudService,
- private bib: BibRecordService,
private cat: CatalogService,
private staffCat: StaffCatalogService
) {}
this.holdFor = 'patron';
this.requestor = this.user = this.auth.user();
this.pickupLib = this.auth.user().ws_ou();
+ this.findRecords();
- // Focus barcode input
- setTimeout(() =>
+ setTimeout(() => // Focus barcode input
this.renderer.selectRootElement('#patron-barcode').focus());
}
+ findRecords() {
+ if (this.holdType === 'T') {
+ this.recordIds = this.holdTargets;
+ } else {
+ // TODO OTHER HOLD TYPES
+ }
+ }
+
holdForChanged() {
console.log('placing hold for ' + this.holdFor);
activeDateSelected(dateStr: string) {
this.activeDate = dateStr;
}
+
+ userBarcodeChanged() {
+ this.user = null;
+
+ if (!this.userBarcode) { return; }
+
+ // Avoid simultaneous lookups caused by firing the
+ // keyup handler and change handler in quick succession.
+ // keyup handler applied so barcode scanner will result
+ // in immediate lookup. change handler for humans
+ // copy/paste'ing then tabbing through the form or off-clicking.
+ if (this.userBarcode === this.barcodeInFlight) { return; }
+ this.barcodeInFlight = this.userBarcode;
+
+ this.net.request(
+ 'open-ils.actor',
+ 'open-ils.actor.get_barcodes',
+ this.auth.token(), this.auth.user().ws_ou(),
+ 'actor', this.userBarcode
+ ).subscribe(barcodes => {
+
+ // Use the first successful barcode response.
+ // TODO: What happens when there are multiple responses?
+ // Use for-loop for early exit since we have async
+ // action within the loop.
+ for (let i = 0; i < barcodes.length; i++) {
+ const bc = barcodes[i];
+ if (!this.evt.parse(bc)) {
+ this.getUser(bc.id);
+ break;
+ }
+ }
+ });
+ }
+
+ getUser(id: number) {
+ // TODO fetch user settings for PU lib, etc.
+ this.pcrud.retrieve('au', id).subscribe(user => {
+ this.user = user;
+ this.notifyPhone = user.day_phone() || user.evening_phone();
+ this.barcodeInFlight = null;
+ });
+ }
}