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