1 import {Component, OnInit, Input} from '@angular/core';
2 import {Router, ActivatedRoute, ParamMap} from '@angular/router';
3 import {NgbNav, NgbNavChangeEvent} from '@ng-bootstrap/ng-bootstrap';
4 import {OrgService} from '@eg/core/org.service';
5 import {IdlObject} from '@eg/core/idl.service';
6 import {NetService} from '@eg/core/net.service';
7 import {PrintService} from '@eg/share/print/print.service';
8 import {PatronService, PatronSummary} from './patron.service';
9 import {ServerStoreService} from '@eg/core/server-store.service';
12 templateUrl: 'summary.component.html',
13 styleUrls: ['summary.component.css'],
14 selector: 'eg-patron-summary'
16 export class PatronSummaryComponent implements OnInit {
18 private _summary: PatronSummary;
19 @Input() set summary(s: PatronSummary) {
20 if (s && this._summary && s.id !== this._summary.id) {
21 this.showDob = this.showDobDefault;
26 get summary(): PatronSummary {
30 showDobDefault = false;
34 private org: OrgService,
35 private net: NetService,
36 private printer: PrintService,
37 private serverStore: ServerStoreService,
38 public patronService: PatronService
42 this.serverStore.getItem('circ.obscure_dob').then(hide => {
43 this.showDobDefault = this.showDob = !hide;
47 p(): IdlObject { // patron shorthand
48 return this.summary ? this.summary.patron : null;
51 hasPrefName(): boolean {
54 this.p().pref_first_given_name() ||
55 this.p().pref_second_given_name() ||
56 this.p().pref_family_name()
61 printAddress(addr: IdlObject) {
63 templateName: 'patron_address',
68 printContext: 'default'
72 copyAddress(addr: IdlObject) {
73 // Note navigator.clipboard requires special permissions.
74 // This is hinky, but gets the job done without the perms.
76 const node = document.getElementById(
77 `patron-address-copy-${addr.id()}`) as HTMLTextAreaElement;
79 // Un-hide the textarea just long enough to copy its data.
80 // Using node.style instead of *ngIf in hopes it
81 // will be quicker, so the user never sees the textarea.
82 node.style.visibility = 'visible';
83 node.style.display = 'block';
87 if (!document.execCommand('copy')) {
88 console.error('Copy command failed');
91 node.style.visibility = 'hidden';
92 node.style.display = 'none';
95 orgSn(orgId: number): string {
96 const org = this.org.get(orgId);
97 return org ? org.shortname() : '';
100 patronStatusColor(): string {
102 const patron = this.p();
104 if (patron.barred() === 't') {
105 return 'PATRON_BARRED';
108 if (patron.active() === 'f') {
109 return 'PATRON_INACTIVE';
112 if (this.summary.stats.fines.balance_owed > 0) {
113 return 'PATRON_HAS_BILLS';
116 if (this.summary.stats.checkouts.overdue > 0) {
117 return 'PATRON_HAS_OVERDUES';
120 if (patron.notes().length > 0) {
121 return 'PATRON_HAS_NOTES';
124 if (this.summary.stats.checkouts.lost > 0) {
125 return 'PATRON_HAS_LOST';
129 let penaltyCount = 0;
131 patron.standing_penalties().some(p => {
134 if (p.standing_penalty().staff_alert() === 't' ||
135 p.standing_penalty().block_list()) {
136 penalty = 'PATRON_HAS_STAFF_ALERT';
140 const name = p.standing_penalty();
143 case 'PATRON_EXCEEDS_CHECKOUT_COUNT':
144 case 'PATRON_EXCEEDS_OVERDUE_COUNT':
145 case 'PATRON_EXCEEDS_FINES':
151 if (penalty) { return penalty; }
153 if (penaltyCount === 1) {
154 return 'ONE_PENALTY';
155 } else if (penaltyCount > 1) {
156 return 'MULTIPLE_PENALTIES';
159 if (patron.juvenile() === 't') {
160 return 'PATRON_JUVENILE';
163 return 'NO_PENALTIES';