]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/eg2/src/app/staff/circ/patron/edit.component.html
LP1904036 Option to invalidate patron Secondary & Other phone
[Evergreen.git] / Open-ILS / src / eg2 / src / app / staff / circ / patron / edit.component.html
1 <eg-string key="circ.patron.edit.test_notify.success" 
2   i18n-text text="Test Notification Sent"></eg-string>
3 <eg-string key="circ.patron.edit.test_notify.fail" 
4   i18n-text text="Test Notification Failed to Send"></eg-string>
5 <eg-string key="circ.patron.edit.invalidate.success" 
6   i18n-text text="Field Invalidation Succeeded"></eg-string>
7 <eg-string key="circ.patron.edit.invalidate.fail" 
8   i18n-text text="Failed to Invalidate Field"></eg-string>
9 <eg-string key="circ.patron.edit.grplink.success" 
10   i18n-text text="Group Link Succeeded"></eg-string>
11 <eg-string key="circ.patron.edit.grplink.fail" 
12   i18n-text text="Group Link Failed"></eg-string>
13 <eg-string key="circ.patron.edit.default_addr_type"
14   i18n-text text="Mailing"></eg-string>
15
16 <eg-patron-secondary-groups [secondaryGroups]="secondaryGroups" #secondaryGroupsDialog>
17 </eg-patron-secondary-groups>
18 <eg-patron-barcodes #barcodesDialog [patron]="patron"></eg-patron-barcodes>
19
20 <eg-alert-dialog #addrAlert
21   i18n-dialogTitle dialogTitle="Address Alert">
22 </eg-alert-dialog>
23
24 <eg-alert-dialog #addrRequiredAlert
25   i18n-dialogTitle dialogTitle="Address Required"
26   i18n-dialogBody dialogBody="An address is required during registration">
27 </eg-alert-dialog>
28
29 <eg-alert-dialog #xactCollisionAlert
30   i18n-dialogTitle dialogTitle="Save Collision"
31   i18n-dialogBody dialogBody="Patron record was modified by another user while you were 
32   editing it. Your changes were not saved; please reapply them.">
33 </eg-alert-dialog>
34
35 <eg-hold-notify-update-dialog #holdNotifyUpdateDialog>
36 </eg-hold-notify-update-dialog>
37
38 <div class="row" *ngIf="!showForm">
39   <div class="col-lg-6 offset-lg-3">
40     <eg-progress-inline></eg-progress-inline>
41   </div>
42 </div>
43
44 <ng-template #fieldExample let-args="args">
45   <span class="ml-2" *ngIf="exampleText(args.cls, args.field)" i18n>
46     Example: {{exampleText(args.cls, args.field)}}
47   </span>
48 </ng-template>
49
50 <!-- IDL-generated field labels.  Override with args.overrideLabel -->
51 <ng-template #fieldLabel let-args="args">
52   <div class="col-lg-3 field-label">
53     <label for="{{getClass(args.cls)}}-{{args.field}}-input">
54       {{getFieldLabel(getClass(args.cls), args.field, args.overrideLabel)}}
55     </label>
56     <eg-help-popover *ngIf="getFieldDoc(args.cls, args.field)"
57       buttonClass="btn-sm text-info p-0 m-0"
58       [placement]="'right'" [helpText]="getFieldDoc(args.cls, args.field)">
59     </eg-help-popover>
60   </div>
61 </ng-template>
62
63 <ng-template #userSettingLabel let-args="args">
64   <div class="col-lg-3 field-label">
65     <label for="cust-{{args.settingName}}-input">
66       {{userSettingTypes[args.settingName].label()}}
67     </label>
68   </div>
69 </ng-template>
70
71 <!-- text / number / email inputs -->
72 <ng-template #fieldInput let-args="args">
73   <div class="col-lg-3">
74     <input 
75       type="{{args.type || 'text'}}"
76       class="form-control" 
77       name="{{getClass(args.cls)}}-{{args.field}}-input"
78       id="{{getClass(args.cls)}}-{{args.field}}-input"
79       [ngModel]="objectFromPath(args.path, args.index)[args.field]()"
80       (ngModelChange)="fieldValueChange(args.path, args.index, args.field, $event)"
81       (change)="afterFieldChange(args.path, args.index, args.field)"
82       [required]="fieldRequired(getClass(args.cls) + '.' + args.field)"
83       [pattern]="fieldPattern(getClass(args.cls), args.field)"
84       [disabled]="args.disabled"
85     />
86   </div>
87 </ng-template>
88
89 <!-- checkbox inputs -->
90 <ng-template #fieldCheckbox let-args="args">
91   <div class="col-lg-3">
92     <input 
93       type="checkbox"
94       class="form-check-input ml-0"
95       name="{{getClass(args.cls)}}-{{args.field}}-input"
96       id="{{getClass(args.cls)}}-{{args.field}}-input"
97       [ngModel]="objectFromPath(args.path, args.index)[args.field]() == 't'"
98       (ngModelChange)="fieldValueChange(args.path, args.index, args.field, $event)"
99       (change)="afterFieldChange(args.path, args.index, args.field)"
100       [pattern]="fieldPattern(getClass(args.cls), args.field)"
101       [disabled]="disabled"
102     />
103   </div>
104 </ng-template>
105
106 <!-- combobox inputs -->
107 <ng-template #fieldCombobox let-args="args">
108   <div class="col-lg-3">
109     <eg-combobox [entries]="args.entries"
110       name="{{getClass(args.cls)}}-{{args.field}}-input"
111       domId="{{getClass(args.cls)}}-{{args.field}}-input"
112       [selectedId]="getFieldValue(args.path, args.index, args.field)"
113       (onChange)="
114         fieldValueChange(args.path, args.index, args.field, $event ? $event.id : null); 
115         afterFieldChange(args.path, args.index, args.field)"
116       [required]="fieldRequired(getClass(args.cls) + '.' + args.field)"
117       [disabled]="args.disabled">
118     </eg-combobox>
119   </div>
120 </ng-template>
121
122 <!-- like fieldRow below, but for user settings checkboxes -->
123 <ng-template #userSettingsCheckboxRow let-args="args">
124   <div class="row pt-1 pb-1 mt-1">
125     <ng-container *ngTemplateOutlet="userSettingLabel; context: {args: args}">
126     </ng-container>
127     <div class="col-lg-3">
128       <input 
129         type="checkbox"
130         class="form-check-input ml-0"
131         name="cust-{{args.settingName}}-input"
132         id="cust-{{args.settingName}}-input"
133         [ngModel]="userSettings[args.settingName]"
134         (ngModelChange)="userSettingChange(args.settingName, $event)"
135         [disabled]="args.disabled"
136       />
137     </div>
138   </div>
139 </ng-template>
140
141 <ng-template #userSettingInput let-args="args">
142   <div class="col-lg-3">
143     <input 
144       type="{{args.type || 'text'}}"
145       class="form-control"
146       name="cust-{{args.settingName}}-input"
147       id="cust-{{args.settingName}}-input"
148       [ngModel]="userSettings[args.settingName]"
149       (ngModelChange)="userSettingChange(args.settingName, $event)"
150       [required]="settingFieldRequired(args.settingName)"
151       [disabled]="args.disabled"
152     />
153   </div>
154 </ng-template>
155
156
157 <ng-template #userSettingInputRow let-args="args">
158   <div class="row pt-1 pb-1 mt-1">
159     <ng-container *ngTemplateOutlet="userSettingLabel; context: {args: args}">
160     </ng-container>
161     <ng-container *ngTemplateOutlet="userSettingInput; context: {args: args}">
162     </ng-container>
163   </div>
164 </ng-template>
165
166
167 <!-- One row of label + field.  
168     Used when a field requires no additional toggles. -->
169 <ng-template #fieldRow let-args="args">
170   <div class="row pt-1 pb-1 mt-1" *ngIf="showField(getClass(args.cls) + '.' + args.field)">
171     <ng-container *ngTemplateOutlet="fieldLabel; context: {args: args}">
172     </ng-container>
173     <ng-container *ngTemplateOutlet="args.template; context: {args: args}">
174     </ng-container>
175     <ng-container *ngTemplateOutlet="fieldExample; context: {args: args}">
176     </ng-container>
177   </div>
178 </ng-template>
179
180
181 <!-- The List O' Fields -->
182
183 <div class="mt-3 striped-rows-even patron-edit-container form-validated" *ngIf="patron && showForm">
184
185   <div class="row pt-1 pb-1 mt-1" *ngIf="showField('ac.barcode')">
186     <ng-container *ngTemplateOutlet="fieldLabel; 
187       context: {args: {cls: 'ac', path: 'card', field: 'barcode'}}">
188     </ng-container>
189     <ng-container *ngTemplateOutlet="fieldInput; context: {args: 
190       {cls: 'ac', path: 'card', field: 'barcode', disabled: !patron.card().isnew()}}">
191     </ng-container>
192     <div class="col-lg-6">
193       <ng-container *ngIf="!patron.isnew()">
194         <button class="btn btn-outline-dark" (click)="replaceBarcode()" i18n>
195           Replace Barcode
196         </button>
197         <button class="btn btn-outline-dark ml-2" (click)="barcodesDialog.open()" i18n>
198           See All
199         </button>
200       </ng-container>
201       <span *ngIf="dupeBarcode" class="text-danger font-weight-bold ml-2" i18n>
202         Barcode is already in use
203       </span>
204     </div>
205   </div>
206
207   <div class="row pt-1 pb-1 mt-1" *ngIf="showField('au.usrname')">
208     <ng-container *ngTemplateOutlet="fieldLabel; context: {args: {field: 'usrname'}}">
209     </ng-container>
210     <ng-container *ngTemplateOutlet="fieldInput; context: {args: {field: 'usrname'}}">
211     </ng-container>
212     <div class="col-lg-6">
213       <span *ngIf="dupeUsername" class="text-danger font-weight-bold ml-2" i18n>
214         Username is already in use
215       </span>
216     </div>
217   </div>
218
219   <div class="row pt-1 pb-1 mt-1">
220     <ng-container *ngTemplateOutlet="fieldLabel; context: {args: {field: 'passwd'}}">
221     </ng-container>
222     <ng-container 
223       *ngTemplateOutlet="fieldInput; context: {args: {field: 'passwd'}}">
224     </ng-container>
225     <div class="col-lg-3">
226       <button class="btn btn-outline-dark" (click)="generatePassword()" i18n>
227         Generate Password
228       </button>
229     </div>
230   </div>
231
232   <!-- Name / Preferred Name Tabs -->
233   <ul ngbNav #nameNav="ngbNav" class="nav-tabs" [(activeId)]="nameTab">
234     <li ngbNavItem="primary">
235       <a ngbNavLink i18n>Primary Name</a>
236       <ng-template ngbNavContent>
237         <ng-container *ngTemplateOutlet="fieldRow; context: 
238           {args: {template: fieldInput, field: 'prefix'}}">
239         </ng-container>
240         <ng-container *ngTemplateOutlet="fieldRow; context: 
241           {args: {template: fieldInput, field: 'first_given_name'}}">
242         </ng-container>
243         <ng-container *ngTemplateOutlet="fieldRow; context: 
244           {args: {template: fieldInput, field: 'second_given_name'}}">
245         </ng-container>
246         <ng-container *ngTemplateOutlet="fieldRow; context: 
247           {args: {template: fieldInput, field: 'family_name'}}">
248         </ng-container>
249         <ng-container *ngTemplateOutlet="fieldRow; context: 
250           {args: {template: fieldInput, field: 'suffix'}}">
251         </ng-container>
252       </ng-template>
253     </li>
254     <li ngbNavItem="preferred">
255       <a ngbNavLink i18n>Preferred Name</a>
256       <ng-template ngbNavContent>
257         <ng-container *ngTemplateOutlet="fieldRow; context: 
258           {args: {template: fieldInput, field: 'pref_prefix'}}">
259         </ng-container>
260         <ng-container *ngTemplateOutlet="fieldRow; context: 
261           {args: {template: fieldInput, field: 'pref_first_given_name'}}">
262         </ng-container>
263         <ng-container *ngTemplateOutlet="fieldRow; context: 
264           {args: {template: fieldInput, field: 'pref_second_given_name'}}">
265         </ng-container>
266         <ng-container *ngTemplateOutlet="fieldRow; context: 
267           {args: {template: fieldInput, field: 'pref_family_name'}}">
268         </ng-container>
269         <ng-container *ngTemplateOutlet="fieldRow; context: 
270           {args: {template: fieldInput, field: 'pref_suffix'}}">
271         </ng-container>
272       </ng-template>
273     </li>
274   </ul>
275
276   <!-- Container div for name / pref name tabs -->
277   <div class="border rounded p-2" [ngClass]="{
278     'border-primary': nameTab == 'primary', 
279     'border-success': nameTab == 'preferred'}">
280     <div [ngbNavOutlet]="nameNav"></div>
281   </div>
282
283   <div class="row pt-1 pb-1 mt-1" *ngIf="showField('au.name_keywords')">
284     <ng-container 
285       *ngTemplateOutlet="fieldLabel; context: {args: {field: 'name_keywords'}}">
286     </ng-container>
287     <div class="col-lg-3">
288       <textarea
289         class="form-control" 
290         name="au-name_keywords-input"
291         id="au-name_keywords-input"
292         [ngModel]="objectFromPath(null, null)['name_keywords']()"
293         (ngModelChange)="fieldValueChange(null, null, 'name_keywords', $event)"
294         (change)="afterFieldChange(null, args.index, 'name_keywords')"
295         [required]="fieldRequired('au.name_keywords')"
296         [pattern]="fieldPattern('au', 'name_keywords')">
297       </textarea>
298     </div>
299   </div>
300
301   <!-- example of overriding a field label -->
302   <eg-string #holdAliasString i18n-text text="Holds Alias"></eg-string>
303   <ng-container *ngTemplateOutlet="fieldRow; context: 
304     {args: {template: fieldInput, field: 'alias', overrideLabel: holdAliasString.text}}">
305   </ng-container>
306
307   <div class="row pt-1 pb-1 mt-1" *ngIf="showField('au.dob')">
308     <ng-container 
309       *ngTemplateOutlet="fieldLabel; context: {args: {field: 'dob'}}">
310     </ng-container>
311     <div class="col-lg-3">
312       <eg-date-select
313         domId="au-dob-input"
314         fieldName="au-dob-input"
315         [noMaxWidth]="true"
316         [initialYmd]="patron.dob()"
317         (onChangeAsIso)="
318           fieldValueChange(null, null, 'dob', $event); 
319           afterFieldChange(null, null, 'dob')"
320         [required]="fieldRequired('au.dob')">
321       </eg-date-select>
322     </div>
323   </div>
324   <ng-container *ngTemplateOutlet="fieldRow; context: 
325     {args: {template: fieldCheckbox, field: 'juvenile'}}">
326   </ng-container>
327   <ng-container *ngTemplateOutlet="fieldRow; context: 
328     {args: {template: fieldInput, field: 'guardian'}}">
329   </ng-container>
330   <ng-container *ngTemplateOutlet="fieldRow; context: 
331     {args: {template: fieldCombobox, field: 'ident_type', entries: identTypes}}">
332   </ng-container>
333   <ng-container *ngTemplateOutlet="fieldRow; context: 
334     {args: {template: fieldInput, field: 'ident_value'}}">
335   </ng-container>
336   <ng-container *ngTemplateOutlet="fieldRow; context: 
337     {args: {template: fieldCombobox, field: 'ident_type2', entries: identTypes}}">
338   </ng-container>
339   <ng-container *ngTemplateOutlet="fieldRow; context: 
340     {args: {template: fieldInput, field: 'ident_value2'}}">
341   </ng-container>
342
343   <div class="row pt-1 pb-1 mt-1">
344     <ng-container 
345       *ngTemplateOutlet="fieldLabel; context: {args: {field: 'email'}}">
346     </ng-container>
347     <ng-container 
348       *ngTemplateOutlet="fieldInput; context: {args: {field: 'email', type: 'email'}}">
349     </ng-container>
350     <div class="col-lg-6">
351       <ng-container *ngIf="patron.email()">
352         <button class="btn btn-outline-dark" 
353           (click)="sendTestMessage('au.email.test')" i18n>
354           Send Test Email
355         </button>
356         <ng-container *ngIf="!patron.isnew()">
357          <button class="btn btn-outline-dark ml-2" 
358            (click)="invalidateField('email')" i18n>Invalidate</button>
359         </ng-container>
360       </ng-container>
361     </div>
362   </div>
363
364   <ng-container 
365     *ngIf="userSettingTypes['circ.send_email_checkout_receipts'] && showField('au.email')">
366     <ng-container *ngTemplateOutlet="userSettingsCheckboxRow; context: 
367       {args: {settingName: 'circ.send_email_checkout_receipts'}}">
368     </ng-container>
369   </ng-container>
370
371   <div class="row pt-1 pb-1 mt-1">
372     <ng-container 
373       *ngTemplateOutlet="fieldLabel; context: {args: {field: 'day_phone'}}">
374     </ng-container>
375     <ng-container 
376       *ngTemplateOutlet="fieldInput; context: {args: {field: 'day_phone'}}">
377     </ng-container>
378     <div class="col-lg-6">
379       <ng-container *ngIf="patron.day_phone() && !patron.isnew()">
380         <button class="btn btn-outline-dark" 
381           (click)="invalidateField('day_phone')" i18n>Invalidate</button>
382       </ng-container>
383       <ng-container *ngTemplateOutlet="fieldExample; context: {args: {field: 'day_phone'}}">
384       </ng-container>
385     </div>
386   </div>
387
388   <div class="row pt-1 pb-1 mt-1">
389     <ng-container 
390       *ngTemplateOutlet="fieldLabel; context: {args: {field: 'evening_phone'}}">
391     </ng-container>
392     <ng-container 
393       *ngTemplateOutlet="fieldInput; context: {args: {field: 'evening_phone'}}">
394     </ng-container>
395     <div class="col-lg-6">
396       <ng-container *ngIf="patron.evening_phone() && !patron.isnew()">
397         <button class="btn btn-outline-dark" 
398           (click)="invalidateField('evening_phone')" i18n>Invalidate</button>
399       </ng-container>
400       <ng-container *ngTemplateOutlet="fieldExample; context: {args: {field: 'evening_phone'}}">
401       </ng-container>
402     </div>
403   </div>
404
405   <div class="row pt-1 pb-1 mt-1">
406     <ng-container 
407       *ngTemplateOutlet="fieldLabel; context: {args: {field: 'other_phone'}}">
408     </ng-container>
409     <ng-container 
410       *ngTemplateOutlet="fieldInput; context: {args: {field: 'other_phone'}}">
411     </ng-container>
412     <div class="col-lg-6">
413       <ng-container *ngIf="patron.other_phone() && !patron.isnew()">
414         <button class="btn btn-outline-dark" 
415           (click)="invalidateField('other_phone')" i18n>Invalidate</button>
416       </ng-container>
417       <ng-container *ngTemplateOutlet="fieldExample; context: {args: {field: 'other_phone'}}">
418       </ng-container>
419     </div>
420   </div>
421
422   <div class="row pt-1 pb-1 mt-1" *ngIf="showField('au.home_ou')">
423     <ng-container 
424       *ngTemplateOutlet="fieldLabel; context: {args: {field: 'home_ou'}}">
425     </ng-container>
426     <div class="col-lg-3">
427       <eg-org-select
428         domId="au-home_ou-input"
429         fieldName="au-home_ou-input"
430         [initialOrgId]="patron.home_ou()"
431         [disableOrgs]="cannotHaveUsersOrgs()"
432         [required]="true"
433         (onChange)="
434           fieldValueChange(null, null, 'home_ou', $event ? $event.id() : null); 
435           afterFieldChange(null, null, 'home_ou')">
436       </eg-org-select>
437     </div>
438   </div>
439
440   <div class="row pt-1 pb-1 mt-1" *ngIf="showField('au.profile')">
441     <ng-container 
442       *ngTemplateOutlet="fieldLabel; context: {args: {field: 'profile'}}">
443     </ng-container>
444     <div class="col-lg-3">
445       <eg-profile-select #profileSelect 
446         [useDisplayEntries]="true"
447         [initialGroupId]="patron.profile()" 
448         [required]="true"
449         (profileChange)="
450           fieldValueChange(null, null, 'profile', $event ? $event.id() : null); 
451           afterFieldChange(null, null, 'profile')">
452       </eg-profile-select>
453     </div>
454     <div class="col-lg-6">
455       <button class="btn btn-outline-dark" 
456         *ngIf="hasPerm.CREATE_USER_GROUP_LINK"
457         (click)="openGroupsDialog()" i18n>Secondary Groups</button>
458     </div>
459   </div>
460
461   <div class="row pt-1 pb-1 mt-1" *ngIf="showField('au.expire_date')">
462     <ng-container 
463       *ngTemplateOutlet="fieldLabel; context: {args: {field: 'expire_date'}}">
464     </ng-container>
465     <div class="col-lg-3">
466       <eg-date-select
467         domId="au-expire_date-input"
468         fieldName="au-expire_date-input"
469         [required]="fieldRequired('au.expire_date')"
470         (onChangeAsIso)="
471           fieldValueChange(null, null, 'expire_date', $event); 
472           afterFieldChange(null, null, 'expire_date')"
473         [(ngModel)]="expireDate">
474       </eg-date-select>
475     </div>
476     <div class="col-lg-6">
477       <button class="btn btn-outline-dark" (click)="setExpireDate()" i18n>
478         Update Expire Date
479       </button>
480     </div>
481   </div>
482   <ng-container *ngTemplateOutlet="fieldRow; context: 
483     {args: {template: fieldCombobox, field: 'net_access_level', entries: inetLevels}}">
484   </ng-container>
485   <ng-container *ngTemplateOutlet="fieldRow; context: 
486     {args: {template: fieldCheckbox, field: 'active'}}">
487   </ng-container>
488   <ng-container *ngTemplateOutlet="fieldRow; context: 
489     {args: {template: fieldCheckbox, field: 'barred'}}">
490   </ng-container>
491   <ng-container *ngTemplateOutlet="fieldRow; context: 
492     {args: {template: fieldCheckbox, field: 'master_account'}}">
493   </ng-container>
494   <ng-container *ngTemplateOutlet="fieldRow; context: 
495     {args: {template: fieldInput, field: 'claims_returned_count', 
496       type: 'number', disabled: !hasPerm.UPDATE_PATRON_CLAIM_RETURN_COUNT}}">
497   </ng-container>
498   <ng-container *ngTemplateOutlet="fieldRow; context: 
499     {args: {template: fieldInput, field: 'claims_never_checked_out_count', 
500       type: 'number', disabled: !hasPerm.UPDATE_PATRON_CLAIM_NEVER_CHECKED_OUT_COUNT}}">
501   </ng-container>
502
503   <div class="alert alert-success pt-2 pb-2 mt-3 mb-3 d-flex">
504     <div class="m-auto font-weight-bold" i18n>User Settings</div>
505   </div>
506
507   <ng-container *ngTemplateOutlet="userSettingInputRow; context: 
508     {args: {settingName: 'opac.default_phone'}}">
509   </ng-container>
510
511   <div class="row pt-1 pb-1 mt-1" *ngIf="showField('au.home_ou')">
512     <ng-container *ngTemplateOutlet="userSettingLabel; 
513       context: {args: {settingName: 'opac.default_pickup_location'}}">
514     </ng-container>
515     <div class="col-lg-3">
516       <eg-org-select
517         domId="cust-opac.default_pickup_location-input"
518         fieldName="cust-opac.default_pickup_location-input"
519         [initialOrgId]="userSettings['opac.default_pickup_location']"
520         [disableOrgs]="cannotHaveVolsOrgs()"
521         (onChange)="userSettingChange(
522           'opac.default_pickup_location', $event ? $event.id() : null)">
523       </eg-org-select>
524     </div>
525   </div>
526
527   <div class="row pt-1 pb-1 mt-1">
528     <ng-container *ngTemplateOutlet="userSettingLabel; 
529       context: {args: {settingName: 'opac.hold_notify'}}">
530     </ng-container>
531     <div class="col-lg-3">
532       <div class="form-check form-check-inline mr-2">
533         <input class="form-check-input" type="checkbox" name="hold-notify-phone" 
534           id="hold-notify-phone" [(ngModel)]="holdNotifyTypes.phone"
535           (ngModelChange)="emitSaveState()"/>
536         <label class="form-check-label" for="hold-notify-phone" i18n>Phone</label>
537       </div>
538       <div class="form-check form-check-inline mr-2">
539         <input class="form-check-input" type="checkbox" name="hold-notify-email" 
540           id="hold-notify-email" [(ngModel)]="holdNotifyTypes.email"
541           (ngModelChange)="emitSaveState()"/>
542         <label class="form-check-label" for="hold-notify-email" i18n>Email</label>
543       </div>
544       <div class="form-check form-check-inline mr-2" 
545         *ngIf="context.settingsCache['sms.enable']">
546         <input class="form-check-input" type="checkbox" name="hold-notify-sms" 
547           id="hold-notify-sms" [(ngModel)]="holdNotifyTypes.sms"
548           (ngModelChange)="emitSaveState()"/>
549         <label class="form-check-label" for="hold-notify-sms" i18n>SMS</label>
550       </div>
551     </div>
552   </div>
553
554   <ng-container *ngIf="context.settingsCache['sms.enable']">
555
556     <div class="row pt-1 pb-1 mt-1">
557       <ng-container *ngTemplateOutlet="userSettingLabel; 
558         context: {args: {settingName: 'opac.default_sms_notify'}}">
559       </ng-container>
560       <ng-container *ngTemplateOutlet="userSettingInput;
561         context: {args: {settingName: 'opac.default_sms_notify'}}">
562       </ng-container>
563       <div class="col-lg-6">
564         <ng-container *ngIf="userSettings['opac.default_sms_notify'] && 
565           userSettings['opac.default_sms_carrier']">
566           <button class="btn btn-outline-dark" 
567             (click)="sendTestMessage('au.sms_text.test')" i18n>
568             Send Test Text
569           </button>
570         </ng-container>
571       </div>
572     </div>
573
574     <div class="row pt-1 pb-1 mt-1">
575       <ng-container *ngTemplateOutlet="userSettingLabel; 
576         context: {args: {settingName: 'opac.default_sms_carrier'}}">
577       </ng-container>
578       <div class="col-lg-3">
579         <eg-combobox [entries]="smsCarriers"
580           name="cust-opac.default_sms_carrier-input"
581           domId="cust-opac.default_sms_carrier-input"
582           [selectedId]="userSettings['opac.default_sms_carrier']"
583           [required]="settingFieldRequired('opac.default_sms_carrier')"
584           (onChange)="userSettingChange(
585             'opac.default_sms_carrier', $event ? $event.id : null)">
586         </eg-combobox>
587       </div>
588     </div>
589   </ng-container>
590
591   <ng-container *ngFor="let set of optInSettingTypes | keyvalue">
592     <ng-container *ngTemplateOutlet="userSettingsCheckboxRow;
593       context: {args: {settingName: set.key}}">
594     </ng-container>
595   </ng-container>
596
597   <ng-container *ngIf="context.settingsCache['circ.privacy_waiver']">
598     <div class="row pt-1 pb-1 mt-1" 
599       *ngFor="let waiver of patron.waiver_entries(); let index = index">
600       <div class="col-lg-3">
601         <span *ngIf="index == 0" i18n>Allow others to use my account</span>
602       </div>
603       <div class="col-lg-3">
604         <input type="text" class="form-control" [ngModel]="waiver.name()"
605           [disabled]="waiver.isdeleted()"
606           (ngModelChange)="fieldValueChange('waiver_entries', index, 'name', $event)"
607           (change)="afterFieldChange('waiver_entries', index, 'name')"
608           i18n-placeholder placeholder="Enter Name..."/>
609       </div>
610       <div class="col-lg-6 d-flex">
611         <div>
612           <div class="form-inline">
613             <input class="form-check-input" type="checkbox" 
614               [disabled]="waiver.isdeleted()"
615               id="waiver-holds-{{waiver.id()}}" [ngModel]="waiver.place_holds() == 't'"
616               (ngModelChange)="fieldValueChange('waiver_entries', index, 'place_holds', $event)"
617               (change)="afterFieldChange('waiver_entries', index, 'place_holds')"/>
618             <label class="form-check-label"
619               for="waiver-holds-{{waiver.id()}}" i18n>Place Holds?</label>
620           </div>
621           <div class="form-inline">
622             <input class="form-check-input" type="checkbox" 
623               [disabled]="waiver.isdeleted()"
624               id="waiver-history-{{waiver.id()}}" [ngModel]="waiver.view_history() == 't'"
625               (ngModelChange)="fieldValueChange('waiver_entries', index, 'view_history', $event)"
626               (change)="afterFieldChange('waiver_entries', index, 'view_history')"/>
627             <label class="form-check-label"
628               for="waiver-history-{{waiver.id()}}" i18n>View Borrowing History?</label>
629           </div>
630         </div>
631         <div class="ml-3">
632           <div class="form-inline">
633             <input class="form-check-input" type="checkbox" 
634               [disabled]="waiver.isdeleted()"
635               id="waiver-pickup-{{waiver.id()}}" [ngModel]="waiver.pickup_holds() == 't'"
636               (ngModelChange)="fieldValueChange('waiver_entries', index, 'pickup_hold', $event)"
637               (change)="afterFieldChange('waiver_entries', index, 'pickup_hold')"/>
638             <label class="form-check-label"
639               for="waiver-pickup-{{waiver.id()}}" i18n>Pick Up Holds?</label>
640           </div>
641           <div class="form-inline">
642             <input class="form-check-input" type="checkbox" 
643               [disabled]="waiver.isdeleted()"
644               id="waiver-checkout-{{waiver.id()}}" [ngModel]="waiver.checkout_items() == 't'"
645               (ngModelChange)="fieldValueChange('waiver_entries', index, 'checkout_items', $event)"
646               (change)="afterFieldChange('waiver_entries', index, 'checkout_items')"/>
647             <label class="form-check-label"
648               for="waiver-checkout-{{waiver.id()}}" i18n>Check Out Items?</label>
649           </div>
650         </div>
651         <div class="ml-3">
652           <button class="btn btn-danger material-icon-button" 
653             [ngClass]="{'invisible': waiver.isdeleted()}"
654             (click)="removeWaiver(waiver)"
655             i18n-title title="Remove Privacy Waiver">
656             <span class="text-danger material-icons">delete</span>
657           </button>
658         </div>
659         <div class="ml-2" *ngIf="index == patron.waiver_entries().length - 1">
660           <button class="btn btn-success material-icon-button" 
661           (click)="addWaiver()" i18n-title title="Add Privacy Waiver">
662             <span class="text-success material-icons">add</span>
663           </button>
664         </div>
665       </div>
666     </div>
667   </ng-container>
668
669   <div class="alert alert-success pt-2 pb-2 mt-3 mb-3 d-flex">
670     <div class="m-auto font-weight-bold" i18n>Addresses</div>
671   </div>
672
673   <ng-container *ngFor="let addr of patron.addresses(); let index = index">
674     <div class="mb-2" *ngIf="!addr.isdeleted()">
675
676       <div class="alert alert-info p-1">
677         <div class="row">
678           <div class="col-lg-3" i18n>Address #{{index + 1}}</div>
679           <div class="col-lg-9">
680             <div class="form-check form-check-inline mr-2">
681               <input class="form-check-input" type="checkbox" 
682                 name="addr-{{addr.id()}}-mailing" id="addr-{{addr.id()}}-mailing" 
683                 [ngModel]="patron.mailing_address() && addr.id() == patron.mailing_address().id()"
684                 (ngModelChange)="setAddrType('mailing', addr, $event)"/>
685               <label class="form-check-label" 
686                 for="addr-{{addr.id()}}-mailing" i18n>Mailing</label>
687             </div>
688             <div class="form-check form-check-inline mr-2">
689               <input class="form-check-input" type="checkbox" 
690                 name="addr-{{addr.id()}}-billing" id="addr-{{addr.id()}}-billing" 
691                 [ngModel]="patron.billing_address() && addr.id() == patron.billing_address().id()"
692                 (ngModelChange)="setAddrType('billing', addr, $event)"/>
693               <label class="form-check-label" 
694                 for="addr-{{addr.id()}}-billing" i18n>Physical</label>
695             </div>
696             <button class="btn btn-danger" (click)="deleteAddr(addr)" i18n>Delete</button>
697           </div>
698         </div>
699       </div>
700       <ng-container *ngTemplateOutlet="fieldRow; context: {args: {template: 
701         fieldInput, field: 'address_type', cls: 'aua', path: 'addresses', index: index}}">
702       </ng-container>
703       <ng-container *ngTemplateOutlet="fieldRow; context: {args: {template: 
704         fieldInput, field: 'post_code', cls: 'aua', path: 'addresses', index: index}}">
705       </ng-container>
706       <ng-container *ngTemplateOutlet="fieldRow; context: {args: {template: 
707         fieldInput, field: 'street1', cls: 'aua', path: 'addresses', index: index}}">
708       </ng-container>
709       <ng-container *ngTemplateOutlet="fieldRow; context: {args: {template: 
710         fieldInput, field: 'street2', cls: 'aua', path: 'addresses', index: index}}">
711       </ng-container>
712       <ng-container *ngTemplateOutlet="fieldRow; context: {args: {template: 
713         fieldInput, field: 'city', cls: 'aua', path: 'addresses', index: index}}">
714       </ng-container>
715       <ng-container *ngTemplateOutlet="fieldRow; context: {args: {template: 
716         fieldInput, field: 'county', cls: 'aua', path: 'addresses', index: index}}">
717       </ng-container>
718       <ng-container *ngTemplateOutlet="fieldRow; context: {args: {template: 
719         fieldInput, field: 'state', cls: 'aua', path: 'addresses', index: index}}">
720       </ng-container>
721       <ng-container *ngTemplateOutlet="fieldRow; context: {args: {template: 
722         fieldInput, field: 'country', cls: 'aua', path: 'addresses', index: index}}">
723       </ng-container>
724       <ng-container *ngTemplateOutlet="fieldRow; context: {args: {template: 
725         fieldCheckbox, field: 'valid', cls: 'aua', path: 'addresses', index: index}}">
726       </ng-container>
727       <ng-container *ngTemplateOutlet="fieldRow; context: {args: {template: 
728         fieldCheckbox, field: 'within_city_limits', cls: 'aua', path: 'addresses', index: index}}">
729       </ng-container>
730     </div>
731   </ng-container>
732
733   <button class="btn btn-success" (click)="newAddr()" i18n>New Address</button>
734
735   <ng-container *ngIf="showField('stat_cats') && statCats.length > 0">
736     <div class="alert alert-success pt-2 pb-2 mt-3 mb-3 d-flex">
737       <div class="m-auto font-weight-bold" i18n>Statistical Categories</div>
738     </div>
739
740     <div class="row pt-1 pb-1 mt-1" *ngFor="let stat of statCats">
741      <div class="col-lg-3 field-label">
742       <label for="asc-{{stat.cat.id()}}-input">{{stat.cat.name()}}</label>
743      </div>
744      <div class="col-lg-3">
745       <eg-combobox
746         domId="asc-{{stat.cat.id()}}-input"
747         name="asc-{{stat.cat.id()}}-input"
748         [entries]="stat.entries"
749         [required]="stat.cat.required() == 1"
750         [allowFreeText]="stat.cat.allow_freetext() == 1"
751         [(ngModel)]="userStatCats[stat.cat.id()]"
752         (onChange)="userStatCatChange(stat.cat, $event)">
753       </eg-combobox>
754      </div>
755     </div>
756   </ng-container>
757
758
759   <ng-container *ngIf="showField('surveys') && surveys.length > 0">
760     <div class="alert alert-success pt-2 pb-2 mt-2 mb-2 d-flex">
761       <div class="m-auto font-weight-bold" i18n>Surveys</div>
762     </div>
763     <div class="card pt-1 pb-1 mt-1" *ngFor="let survey of surveys">
764       <div class="card-header">{{survey.name()}}</div>
765       <div class="card-body">
766         <div class="row pt-1 pb-1 mt-1" *ngFor="let question of survey.questions()">
767           <div class="col-lg-3 field-label">
768             <label for="asvq-{{question.id()}}-input">{{question.question()}}</label>
769           </div>
770           <div class="col-lg-3">
771             <eg-combobox
772               domId="asvq-{{question.id()}}-input"
773               name="asvq-{{question.id()}}-input"
774               [entries]="surveyQuestionAnswers(question)"
775               (onChange)="applySurveyResponse(question, $event)">
776             </eg-combobox>
777           </div>
778         </div>
779       </div>
780     </div>
781   </ng-container>
782
783 </div>
784