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