]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/eg2/src/app/staff/catalog/hold/hold.component.html
LP2043899 Revised org select field labels
[Evergreen.git] / Open-ILS / src / eg2 / src / app / staff / catalog / hold / hold.component.html
1
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>
5
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">
11 </eg-alert-dialog>
12
13 <div class="row">
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>
19     </button>
20   </div>
21   <div class="col-lg-5">
22     <ng-container *ngIf="badBarcode">
23       <div class="alert alert-danger" i18n>
24         Barcode '{{badBarcode}}' not found.
25       </div>
26     </ng-container>
27     <ng-container *ngIf="!badBarcode">
28       <h3 i18n>Place Hold
29         <small *ngIf="user">
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()}})
32         </small>
33       </h3>
34     </ng-container>
35   </div>
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>
40     </button>
41   </div>
42 </div>
43
44 <form class="form form-validated common-form"
45   autocomplete="off" (keydown.enter)="$event.preventDefault()">
46   <div class="row">
47     <div class="col-lg-6 common-form striped-odd">
48       <div class="row mt-2">
49         <div class="col-lg-6">
50           <div class="form-check">
51             <input class="form-check-input" type="radio"
52               (change)="holdForChanged()"
53               id="hold-for-patron"
54               name="holdFor" value="patron" [(ngModel)]="holdFor"/>
55             <label class="form-label form-check-label" for="hold-for-patron" i18n>
56               Place hold for patron by barcode:
57             </label>
58           </div>
59         </div>
60         <div class="col-lg-6">
61           <div class="input-group">
62             <input type='text' class="form-control" name="userBarcode"
63               [disabled]="holdFor!=='patron'" id='patron-barcode'
64               aria-label="Patron barcode" i18n-aria-label
65               (ngModelChange)="debounceUserBarcodeLookup($event)"
66               (paste)="debounceUserBarcodeLookup($event)"
67               [(ngModel)]="userBarcode"/>
68             <div class="input-group-text">
69               <button class="btn btn-outline-dark" (click)="userBarcodeChanged()">Submit</button>
70             </div>
71           </div>
72         </div>
73       </div>
74       <div class="row mt-2">
75         <div class="col-lg-6">
76           <div class="form-check">
77             <input class="form-check-input" type="radio"
78               (change)="holdForChanged()"
79               id="hold-for-staff"
80               name="holdFor" value="staff" [(ngModel)]="holdFor"/>
81             <label class="form-label form-check-label" i18n for="hold-for-staff">
82               Place hold for this staff account:
83             </label>
84           </div>
85         </div>
86         <div class="col-lg-6 fw-bold">{{requestor.usrname()}}</div>
87       </div>
88       <div class="row mt-2">
89         <div class="col-lg-6">
90           <label class="form-label" for="pickupLibSelect" i18n>Pickup Location: </label>
91         </div>
92         <div class="col-lg-6">
93           <eg-org-select domId="pickupLibSelect" (onChange)="pickupLib = $event ? $event.id() : null"
94             [disableOrgs]="disableOrgs" [applyOrgId]="pickupLib"></eg-org-select>
95         </div>
96       </div>
97       <div class="row mt-2">
98         <div class="col-lg-6">
99           <div class="form-check">
100             <input class="form-check-input" type="checkbox" id="suspend"
101               name="suspend" [(ngModel)]="suspend"/>
102             <label class="form-label form-check-label" for="suspend" i18n>Suspend Hold</label>
103           </div>
104         </div>
105         <div class="col-lg-6">
106           <div [ngClass]="{'border border-danger rounded': activeDateInvalid}">
107             <eg-date-select [(ngModel)]="activeDate" name='active-date'
108               (onChangeAsYmd)="activeDateYmd = $event"
109               (onChangeAsDate)="setActiveDate($event)"
110               (onChangeAsIso)="activeDateSelected($event)" [disabled]="!suspend">
111             </eg-date-select>
112           </div>
113         </div>
114       </div>
115       <div class="row mt-2" *ngIf="multiHoldsActive">
116         <div class="col-lg-6">
117           <label class="form-label" for='multi-hold-count' i18n>Number of copies:</label>
118         </div>
119         <div class="col-lg-6">
120           <select class="form-select" name="multi-hold-count"
121             id="multi-hold-count" [(ngModel)]="multiHoldCount">
122             <option [value]="num"
123               *ngFor="let num of holdCountRange()">{{num}}</option>
124           </select>
125         </div>
126       </div>
127
128     </div><!-- left column -->
129     <div class="col-lg-6">
130       <div class="card">
131         <div class="card-header">
132           <h4 i18n>Notifications</h4>
133         </div>
134         <ul class="list-group list-group-flush">
135           <li class="list-group-item d-flex">
136             <div class="flex-1">
137               <div class="form-check">
138                 <input class="form-check-input" type="checkbox" name="notifyEmail"
139                   id="notifyEmail"
140                   [disabled]="!user || !user.email()" [(ngModel)]="notifyEmail"/>
141                 <label class="form-label form-check-label" for="notifyEmail" i18n>Notify by Email</label>
142               </div>
143             </div>
144             <div class="flex-1">
145               <div class="input-group">
146                 <label for="userEmail" class="form-label input-group-text" i18n>Email Address</label>
147                 <input type="text" class="form-control" name="userEmail"
148                   id="userEmail"
149                   [disabled]="true" value="{{user ? user.email() : ''}}"/>
150               </div>
151             </div>
152           </li>
153           <li class="list-group-item d-flex">
154             <div class="flex-1">
155               <div class="form-check">
156                 <input class="form-check-input" type="checkbox"
157                   id="notifyPhone"
158                   name="notifyPhone" [(ngModel)]="notifyPhone"/>
159                 <label class="form-label form-check-label" for="notifyPhone" i18n>Notify by Phone</label>
160               </div>
161             </div>
162             <div class="flex-1">
163               <div class="input-group">
164                 <label for="phoneValue"  class="form-label input-group-text" i18n>Phone Number</label>
165                 <input type="text" class="form-control" [disabled]="!notifyPhone"
166                   name="phoneValue" id="phoneValue" [(ngModel)]="phoneValue"/>
167               </div>
168             </div>
169           </li>
170           <li *ngIf="smsEnabled" class="list-group-item d-flex">
171             <div class="flex-1">
172               <div class="form-check">
173                 <input class="form-check-input" type="checkbox" id="notifySms"
174                   name="notifySms" [(ngModel)]="notifySms"/>
175                 <label class="form-label form-check-label" for="notifySms" i18n>Notify by SMS</label>
176               </div>
177             </div>
178             <div class="flex-1">
179               <div class="input-group">
180                 <label for="smsValue"  class="form-label input-group-text" i18n>SMS Number</label>
181                 <input type="text" class="form-control" [disabled]="!notifySms"
182                   id="smsValue" name="smsValue" [(ngModel)]="smsValue"
183                   [required]="notifySms"/>
184               </div>
185             </div>
186           </li>
187           <li *ngIf="smsEnabled" class="list-group-item d-flex">
188             <div class="flex-1">
189               <label class="form-label" for="smsCarriers" i18n>SMS Carrier</label>
190             </div>
191             <div class="flex-1">
192               <eg-combobox [disabled]="!notifySms" #smsCbox
193                 domId="smsCarriers" [required]="notifySms"
194                 placeholder="SMS Carriers" i18n-placeholder
195                 [entries]="smsCarriers">
196               </eg-combobox>
197             </div>
198           </li>
199           <li class="list-group-item">
200             <button class="btn btn-success" (click)="placeHolds()"
201               [disabled]="!readyToPlaceHolds()" i18n>Place Hold(s)</button>
202             <button class="btn btn-outline-dark ms-2" (click)="resetForm()" i18n>Reset</button>
203           </li>
204         </ul><!-- col -->
205       </div><!-- row -->
206     </div><!--card -->
207   </div><!-- col -->
208 </form>
209
210 <div class="row"><div class="col-lg-12"><hr/></div></div>
211
212 <div class="row pt-3 ms-1 me-1 d-flex">
213   <div class="">
214     <span class="fw-bold" i18n>Placing
215       <ng-container *ngIf="holdType === 'M'">METARECORD</ng-container>
216       <ng-container *ngIf="holdType === 'T'">TITLE</ng-container>
217       <ng-container *ngIf="holdType === 'V'">CALL NUMBER</ng-container>
218       <ng-container *ngIf="holdType === 'F'">FORCE ITEM</ng-container>
219       <ng-container *ngIf="holdType === 'C'">ITEM</ng-container>
220       <ng-container *ngIf="holdType === 'R'">RECALL</ng-container>
221       <ng-container *ngIf="holdType === 'I'">ISSUANCE</ng-container>
222       <ng-container *ngIf="holdType === 'P'">PARTS</ng-container>
223       hold on record(s)
224     </span>
225   </div>
226   <div class="flex-1"> </div>
227   <div>
228     <span class="ps-3" *ngIf="isItemHold()">
229       <span i18n>Item-Level Hold Options:</span>
230       <span class="ps-2">
231         <a routerLink="/staff/catalog/hold/C" queryParamsHandling="merge">
232           <button [disabled]="holdType === 'C'" class="btn btn-outline-primary"
233             i18n>Item Hold</button>
234         </a>
235       </span>
236       <span class="ps-2">
237         <a routerLink="/staff/catalog/hold/R" queryParamsHandling="merge">
238           <button [disabled]="holdType === 'R'" class="btn btn-outline-primary"
239             i18n>Recall Hold</button>
240         </a>
241       </span>
242       <span class="ps-2">
243         <a routerLink="/staff/catalog/hold/F" queryParamsHandling="merge">
244           <button [disabled]="holdType === 'F'" class="btn btn-outline-primary"
245             i18n>Force Item Hold</button>
246         </a>
247       </span>
248     </span>
249   </div>
250 </div>
251
252 <ng-template #anyValue>
253   <span class="fst-italic" i18n>ANY</span>
254 </ng-template>
255
256 <!--
257     TODO: add a section per hold context for metarecord holds
258     listing the possible formats and languages.
259
260     TODO: add a secion per hold context for T holds providing a
261     link to the metarecord hold equivalent (AKA "Advanced Hold
262     Options") for each record that has selectable filters (and
263     only when metarecord holds are enabled).
264 -->
265
266 <div class="hold-records-list common-form striped-even">
267
268   <div class="row mt-2 ms-1 me-1 fw-bold">
269     <div class="col-lg-1" i18n>Format</div>
270     <div class="col-lg-2" i18n>Title</div>
271     <div class="col-lg-1" i18n>Author</div>
272     <div class="col-lg-2" i18n>Part</div>
273     <div class="col-lg-2" i18n>Call Number</div>
274     <div class="col-lg-1" i18n>Barcode</div>
275     <div class="col-lg-2" i18n>Holds Status</div>
276     <div class="col-lg-1" i18n>Override</div>
277   </div>
278   <div class="row mt-1 ms-1 me-1" *ngIf="showOverrideAll()">
279     <div class="col-lg-12">
280       <div class="row">
281         <div class="col-lg-1 ms-auto">
282           <button class="btn btn-info" i18n
283             (click)="overrideAll()">
284             Override All
285           </button>
286         </div>
287       </div>
288     </div>
289   </div>
290   <div class="row mt-1 ms-1 me-1" *ngFor="let ctx of holdContexts">
291     <div class="col-lg-12" *ngIf="ctx.holdMeta">
292       <div class="row">
293         <div class="col-lg-1">
294           <ng-container
295             *ngFor="let code of ctx.holdMeta.bibSummary.attributes.icon_format">
296             <img class="pe-1"
297               alt=""
298               src="/images/format_icons/icon_format/{{code}}.png"/>
299           </ng-container>
300         </div>
301         <!-- TODO: link for a metarecord should
302             jump to constituent bib list search page? -->
303         <div class="col-lg-2">
304           <a routerLink="/staff/catalog/record/{{ctx.holdMeta.bibId}}">
305             {{ctx.holdMeta.bibSummary.display.title}}
306           </a>
307         </div>
308         <div class="col-lg-1">{{ctx.holdMeta.bibSummary.display.author}}</div>
309         <div class="col-lg-2">
310           <ng-container *ngIf="ctx.holdMeta.parts.length">
311             <select class="form-select"  (change)="setPart(ctx, $event)"
312               [ngModel]="ctx.holdMeta.part ? ctx.holdMeta.part.id() : (ctx.holdMeta.part_required ? ctx.holdMeta.parts[0].id() : '')">
313               <option *ngIf="!ctx.holdMeta.part_required" value="" i18n>Any Part</option>
314               <option *ngFor="let part of ctx.holdMeta.parts"
315                 value="{{part.id()}}">{{part.label()}}</option>
316             </select>
317           </ng-container>
318           <ng-container *ngIf="ctx.holdMeta.parts.length === 0">
319             <ng-container *ngIf="ctx.holdMeta.part">
320               <span>{{ctx.holdMeta.part.label()}}</span>
321             </ng-container>
322             <ng-container *ngIf="!ctx.holdMeta.part">
323               <span i18n>N/A</span>
324             </ng-container>
325           </ng-container>
326         </div>
327         <div class="col-lg-2">
328           <ng-container *ngIf="ctx.holdMeta.callNum; else anyValue">
329             {{ctx.holdMeta.callNum.label()}}
330           </ng-container>
331         </div>
332         <div class="col-lg-1">
333           <ng-container *ngIf="ctx.holdMeta.copy; else anyValue">
334             {{ctx.holdMeta.copy.barcode()}}
335           </ng-container>
336         </div>
337         <div class="col-lg-2">
338           <ng-container *ngIf="!ctx.lastRequest && !ctx.processing">
339             <div class="alert alert-info p-1 ms-2" i18n>Hold Pending</div>
340           </ng-container>
341           <ng-container *ngIf="ctx.processing">
342             <div class="alert alert-primary p-1 ms-2" i18n>Hold Processing...</div>
343           </ng-container>
344           <ng-container *ngIf="ctx.lastRequest">
345             <ng-container *ngIf="ctx.lastRequest.result.success">
346               <div class="alert alert-success p-1 ms-2" i18n>Hold Succeeded</div>
347             </ng-container>
348             <ng-container *ngIf="!ctx.lastRequest.result.success">
349               <div class="alert alert-danger p-1 ms-2"
350                 title="{{ctx.lastRequest.result.evt.textcode}}">
351                 {{ctx.lastRequest.result.evt.textcode}}
352               </div>
353             </ng-container>
354           </ng-container>
355         </div>
356         <div class="col-lg-1">
357           <ng-container *ngIf="canOverride(ctx)">
358             <button class="btn btn-info" (click)="override(ctx)">Override</button>
359           </ng-container>
360         </div>
361       </div>
362       <!-- note: using inline style since class-level styling for rows
363           is superseded by the striped-even styling of the container -->
364       <div class="row" *ngIf="hasMetaFilters(ctx)"
365         style="background-color:inherit; border:none">
366         <div class="col-lg-1"><label class="form-label" i18n>Formats: </label></div>
367         <div class="col-lg-11 d-flex">
368           <ng-container
369             *ngFor="let ccvm of ctx.holdMeta.metarecord_filters.formats">
370             <div class="form-check ms-3">
371               <label class="form-label form-check-label ms-1" for="hold-include-format-{{ccvm.code()}}">
372               <input class="form-check-input" type="checkbox" id="hold-include-format-{{ccvm.code()}}"
373                 [disabled]="ctx.holdMeta.metarecord_filters.formats.length === 1"
374                 [(ngModel)]="ctx.selectedFormats.formats[ccvm.code()]"/>
375               <img class="ms-1"
376                 alt=""
377                 src="/images/format_icons/icon_format/{{ccvm.code()}}.png"/>
378
379                 {{ccvm.search_label() || ccvm.value()}}
380               </label>
381             </div>
382           </ng-container>
383         </div>
384       </div>
385       <div class="row" *ngIf="hasMetaFilters(ctx)"
386         style="background-color:inherit; border:none">
387         <div class="col-lg-1"><label class="form-label" i18n>Languages: </label></div>
388         <div class="col-lg-11 d-flex">
389           <ng-container
390             *ngFor="let ccvm of ctx.holdMeta.metarecord_filters.langs">
391             <div class="form-check ms-3">
392               <label class="form-label form-check-label ms-1" for="hold-include-lang-{{ccvm.value()}}">
393               <input class="form-check-input" type="checkbox" id="hold-include-lang-{{ccvm.value()}}"
394                 [disabled]="ctx.holdMeta.metarecord_filters.langs.length === 1"
395                 [(ngModel)]="ctx.selectedFormats.langs[ccvm.code()]"/>
396
397                 {{ccvm.search_label() || ccvm.value()}}
398               </label>
399             </div>
400           </ng-container>
401         </div>
402       </div>
403     </div>
404   </div>
405 </div>
406
407