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