2 <eg-patron-search-dialog #patronSearch></eg-patron-search-dialog>
3 <eg-barcode-select #barcodeSelect></eg-barcode-select>
4 <eg-worklog-strings-components></eg-worklog-strings-components>
6 <eg-alert-dialog #activeDateAlert
7 i18n-dialogTitle i18n-dialogBody
8 dialogTitle="Invalid Hold Activation Date"
9 dialogBody="Hold activation date {{activeDateYmd}} is not valid.
10 Please chose a date in the future">
14 <div class="col-lg-1">
15 <button type="button" class="btn btn-info label-with-material-icon"
16 (click)="goBack()" [disabled]="hasNoHistory()">
17 <span class="material-icons" aria-hidden="true">keyboard_backspace</span>
18 <span i18n>Return</span>
21 <div class="col-lg-5">
22 <ng-container *ngIf="badBarcode">
23 <div class="alert alert-danger" i18n>
24 Barcode '{{badBarcode}}' not found.
27 <ng-container *ngIf="!badBarcode">
30 ({{user.pref_family_name() ? user.pref_family_name() : user.family_name()}},
31 {{user.pref_first_given_name() ? user.pref_first_given_name() :user.first_given_name()}})
36 <div class="col-lg-2">
37 <button type="button" class="btn btn-outline-dark btn-sm" (click)="searchPatrons()">
38 <span class="material-icons mat-icon-in-button align-middle" aria-hidden="true">search</span>
39 <span class="align-middle" i18n>Search for Patron</span>
44 <!-- eslint-disable @angular-eslint/template/accessibility-interactive-supports-focus -->
45 <form class="form form-validated common-form"
46 autocomplete="off" (keydown.enter)="$event.preventDefault()">
47 <!-- eslint-enable @angular-eslint/template/accessibility-interactive-supports-focus -->
49 <div class="col-lg-6 common-form striped-odd">
50 <div class="row mt-2">
51 <div class="col-lg-6">
52 <div class="form-check">
53 <input class="form-check-input" type="radio"
54 (change)="holdForChanged()"
56 name="holdFor" value="patron" [(ngModel)]="holdFor"/>
57 <label class="form-label form-check-label" for="hold-for-patron" i18n>
58 Place hold for patron by barcode:
62 <div class="col-lg-6">
63 <div class="input-group">
64 <input type='text' class="form-control" name="userBarcode"
65 [disabled]="holdFor!=='patron'" id='patron-barcode'
66 aria-label="Patron barcode" i18n-aria-label
67 (ngModelChange)="debounceUserBarcodeLookup($event)"
68 (paste)="debounceUserBarcodeLookup($event)"
69 [(ngModel)]="userBarcode"/>
70 <div class="input-group-text">
71 <button type="button" class="btn btn-outline-dark" (click)="userBarcodeChanged()">Submit</button>
76 <div class="row mt-2">
77 <div class="col-lg-6">
78 <div class="form-check">
79 <input class="form-check-input" type="radio"
80 (change)="holdForChanged()"
82 name="holdFor" value="staff" [(ngModel)]="holdFor"/>
83 <label class="form-label form-check-label" i18n for="hold-for-staff">
84 Place hold for this staff account:
88 <div class="col-lg-6 fw-bold">{{requestor.usrname()}}</div>
90 <div class="row mt-2">
91 <div class="col-lg-6">
92 <label class="form-label" for="pickupLibSelect" i18n>Pickup Location: </label>
94 <div class="col-lg-6">
95 <eg-org-select domId="pickupLibSelect" (onChange)="pickupLib = $event ? $event.id() : null"
96 [disableOrgs]="disableOrgs" [applyOrgId]="pickupLib" [required]="true"></eg-org-select>
99 <div class="row mt-2">
100 <div class="col-lg-6">
101 <div class="form-check">
102 <input class="form-check-input" type="checkbox" id="suspend"
103 name="suspend" [(ngModel)]="suspend"/>
104 <label class="form-label form-check-label" for="suspend" i18n>Suspend Hold</label>
107 <div class="col-lg-6">
108 <div [ngClass]="{'border border-danger rounded': activeDateInvalid}">
109 <eg-date-select [(ngModel)]="activeDate" name='active-date'
110 (onChangeAsYmd)="activeDateYmd = $event"
111 (onChangeAsDate)="setActiveDate($event)"
112 (onChangeAsIso)="activeDateSelected($event)" [disabled]="!suspend">
117 <div class="row mt-2" *ngIf="multiHoldsActive">
118 <div class="col-lg-6">
119 <label class="form-label" for='multi-hold-count' i18n>Number of copies:</label>
121 <div class="col-lg-6">
122 <select class="form-select" name="multi-hold-count"
123 id="multi-hold-count" [(ngModel)]="multiHoldCount">
124 <option [value]="num"
125 *ngFor="let num of holdCountRange()">{{num}}</option>
130 </div><!-- left column -->
131 <div class="col-lg-6">
133 <div class="card-header">
134 <h4 i18n>Notifications</h4>
136 <ul class="list-group list-group-flush">
137 <li class="list-group-item d-flex">
139 <div class="form-check">
140 <input class="form-check-input" type="checkbox" name="notifyEmail"
142 [disabled]="!user || !user.email()" [(ngModel)]="notifyEmail"/>
143 <label class="form-label form-check-label" for="notifyEmail" i18n>Notify by Email</label>
147 <div class="input-group">
148 <label for="userEmail" class="form-label input-group-text" i18n>Email Address</label>
149 <input type="text" class="form-control" name="userEmail"
151 [disabled]="true" value="{{user ? user.email() : ''}}"/>
155 <li class="list-group-item d-flex">
157 <div class="form-check">
158 <input class="form-check-input" type="checkbox"
160 name="notifyPhone" [(ngModel)]="notifyPhone"/>
161 <label class="form-label form-check-label" for="notifyPhone" i18n>Notify by Phone</label>
165 <div class="input-group">
166 <label for="phoneValue" class="form-label input-group-text" i18n>Phone Number</label>
167 <input type="text" class="form-control" [disabled]="!notifyPhone"
168 name="phoneValue" id="phoneValue" [(ngModel)]="phoneValue"/>
172 <li *ngIf="smsEnabled" class="list-group-item d-flex">
174 <div class="form-check">
175 <input class="form-check-input" type="checkbox" id="notifySms"
176 name="notifySms" [(ngModel)]="notifySms"/>
177 <label class="form-label form-check-label" for="notifySms" i18n>Notify by SMS</label>
181 <div class="input-group">
182 <label for="smsValue" class="form-label input-group-text" i18n>SMS Number</label>
183 <input type="text" class="form-control" [disabled]="!notifySms"
184 id="smsValue" name="smsValue" [(ngModel)]="smsValue"
185 [required]="notifySms"/>
189 <li *ngIf="smsEnabled" class="list-group-item d-flex">
191 <label class="form-label" for="smsCarriers" i18n>SMS Carrier</label>
194 <eg-combobox [disabled]="!notifySms" #smsCbox
195 domId="smsCarriers" [required]="notifySms"
196 placeholder="SMS Carriers" i18n-placeholder
197 [entries]="smsCarriers">
201 <li class="list-group-item">
202 <button type="button" class="btn btn-success" (click)="placeHolds()"
203 [disabled]="!readyToPlaceHolds()" i18n>Place Hold(s)</button>
204 <button type="button" class="btn btn-outline-dark ms-2" (click)="resetForm()" i18n>Reset</button>
212 <div class="row"><div class="col-lg-12"><hr/></div></div>
214 <div class="row pt-3 ms-1 me-1 d-flex">
216 <span class="fw-bold" i18n>Placing
217 <ng-container *ngIf="holdType === 'M'">METARECORD</ng-container>
218 <ng-container *ngIf="holdType === 'T'">TITLE</ng-container>
219 <ng-container *ngIf="holdType === 'V'">CALL NUMBER</ng-container>
220 <ng-container *ngIf="holdType === 'F'">FORCE ITEM</ng-container>
221 <ng-container *ngIf="holdType === 'C'">ITEM</ng-container>
222 <ng-container *ngIf="holdType === 'R'">RECALL</ng-container>
223 <ng-container *ngIf="holdType === 'I'">ISSUANCE</ng-container>
224 <ng-container *ngIf="holdType === 'P'">PARTS</ng-container>
228 <div class="flex-1"> </div>
230 <span class="ps-3" *ngIf="isItemHold()">
231 <span i18n>Item-Level Hold Options:</span>
233 <a routerLink="/staff/catalog/hold/C" queryParamsHandling="merge">
234 <button type="button" [disabled]="holdType === 'C'" class="btn btn-outline-primary"
235 i18n>Item Hold</button>
239 <a routerLink="/staff/catalog/hold/R" queryParamsHandling="merge">
240 <button type="button" [disabled]="holdType === 'R'" class="btn btn-outline-primary"
241 i18n>Recall Hold</button>
245 <a routerLink="/staff/catalog/hold/F" queryParamsHandling="merge">
246 <button type="button" [disabled]="holdType === 'F'" class="btn btn-outline-primary"
247 i18n>Force Item Hold</button>
254 <ng-template #anyValue>
255 <span class="fst-italic" i18n>ANY</span>
259 TODO: add a section per hold context for metarecord holds
260 listing the possible formats and languages.
262 TODO: add a secion per hold context for T holds providing a
263 link to the metarecord hold equivalent (AKA "Advanced Hold
264 Options") for each record that has selectable filters (and
265 only when metarecord holds are enabled).
268 <div class="hold-records-list common-form striped-even">
270 <div class="row mt-2 ms-1 me-1 fw-bold">
271 <div class="col-lg-1" i18n>Format</div>
272 <div class="col-lg-2" i18n>Title</div>
273 <div class="col-lg-1" i18n>Author</div>
274 <div class="col-lg-2" i18n>Part</div>
275 <div class="col-lg-2" i18n>Call Number</div>
276 <div class="col-lg-1" i18n>Barcode</div>
277 <div class="col-lg-2" i18n>Holds Status</div>
278 <div class="col-lg-1" i18n>Override</div>
280 <div class="row mt-1 ms-1 me-1" *ngIf="showOverrideAll()">
281 <div class="col-lg-12">
283 <div class="col-lg-1 ms-auto">
284 <button type="button" class="btn btn-info" i18n
285 (click)="overrideAll()">
292 <div class="row mt-1 ms-1 me-1" *ngFor="let ctx of holdContexts">
293 <div class="col-lg-12" *ngIf="ctx.holdMeta">
295 <div class="col-lg-1">
297 *ngFor="let code of ctx.holdMeta.bibSummary.attributes.icon_format">
300 src="/images/format_icons/icon_format/{{code}}.png"/>
303 <!-- TODO: link for a metarecord should
304 jump to constituent bib list search page? -->
305 <div class="col-lg-2">
306 <a routerLink="/staff/catalog/record/{{ctx.holdMeta.bibId}}">
307 {{ctx.holdMeta.bibSummary.display.title}}
310 <div class="col-lg-1">{{ctx.holdMeta.bibSummary.display.author}}</div>
311 <div class="col-lg-2">
312 <ng-container *ngIf="ctx.holdMeta.parts.length">
313 <select class="form-select" (change)="setPart(ctx, $event)"
314 [ngModel]="ctx.holdMeta.part ? ctx.holdMeta.part.id() : (ctx.holdMeta.part_required ? ctx.holdMeta.parts[0].id() : '')">
315 <option *ngIf="!ctx.holdMeta.part_required" value="" i18n>Any Part</option>
316 <option *ngFor="let part of ctx.holdMeta.parts"
317 value="{{part.id()}}">{{part.label()}}</option>
320 <ng-container *ngIf="ctx.holdMeta.parts.length === 0">
321 <ng-container *ngIf="ctx.holdMeta.part">
322 <span>{{ctx.holdMeta.part.label()}}</span>
324 <ng-container *ngIf="!ctx.holdMeta.part">
325 <span i18n>N/A</span>
329 <div class="col-lg-2">
330 <ng-container *ngIf="ctx.holdMeta.callNum; else anyValue">
331 {{ctx.holdMeta.callNum.label()}}
334 <div class="col-lg-1">
335 <ng-container *ngIf="ctx.holdMeta.copy; else anyValue">
336 {{ctx.holdMeta.copy.barcode()}}
339 <div class="col-lg-2">
340 <ng-container *ngIf="!ctx.lastRequest && !ctx.processing">
341 <div class="alert alert-info p-1 ms-2" i18n>Hold Pending</div>
343 <ng-container *ngIf="ctx.processing">
344 <div class="alert alert-primary p-1 ms-2" i18n>Hold Processing...</div>
346 <ng-container *ngIf="ctx.lastRequest">
347 <ng-container *ngIf="ctx.lastRequest.result.success">
348 <div class="alert alert-success p-1 ms-2" i18n>Hold Succeeded</div>
350 <ng-container *ngIf="!ctx.lastRequest.result.success">
351 <div class="alert alert-danger p-1 ms-2"
352 title="{{ctx.lastRequest.result.evt.textcode}}">
353 {{ctx.lastRequest.result.evt.textcode}}
358 <div class="col-lg-1">
359 <ng-container *ngIf="canOverride(ctx)">
360 <button type="button" class="btn btn-info" (click)="override(ctx)">Override</button>
364 <!-- note: using inline style since class-level styling for rows
365 is superseded by the striped-even styling of the container -->
366 <div class="row" *ngIf="hasMetaFilters(ctx)"
367 style="background-color:inherit; border:none">
368 <div class="col-lg-1"><label class="form-label" i18n>Formats: </label></div>
369 <div class="col-lg-11 d-flex">
371 *ngFor="let ccvm of ctx.holdMeta.metarecord_filters.formats">
372 <div class="form-check ms-3">
373 <label class="form-label form-check-label ms-1" for="hold-include-format-{{ccvm.code()}}">
374 <input class="form-check-input" type="checkbox" id="hold-include-format-{{ccvm.code()}}"
375 [disabled]="ctx.holdMeta.metarecord_filters.formats.length === 1"
376 [(ngModel)]="ctx.selectedFormats.formats[ccvm.code()]"/>
379 src="/images/format_icons/icon_format/{{ccvm.code()}}.png"/>
381 {{ccvm.search_label() || ccvm.value()}}
387 <div class="row" *ngIf="hasMetaFilters(ctx)"
388 style="background-color:inherit; border:none">
389 <div class="col-lg-1"><label class="form-label" i18n>Languages: </label></div>
390 <div class="col-lg-11 d-flex">
392 *ngFor="let ccvm of ctx.holdMeta.metarecord_filters.langs">
393 <div class="form-check ms-3">
394 <label class="form-label form-check-label ms-1" for="hold-include-lang-{{ccvm.value()}}">
395 <input class="form-check-input" type="checkbox" id="hold-include-lang-{{ccvm.value()}}"
396 [disabled]="ctx.holdMeta.metarecord_filters.langs.length === 1"
397 [(ngModel)]="ctx.selectedFormats.langs[ccvm.code()]"/>
399 {{ccvm.search_label() || ccvm.value()}}