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