From 8f36f2e85cd81555d44eed9b4fe4c39488d59de0 Mon Sep 17 00:00:00 2001 From: Bill Erickson <berickxx@gmail.com> Date: Tue, 2 Mar 2021 10:43:59 -0500 Subject: [PATCH] LP1904036 print/copy patron address; summary styling Signed-off-by: Bill Erickson <berickxx@gmail.com> Signed-off-by: Jane Sandberg <js7389@princeton.edu> Signed-off-by: Galen Charlton <gmc@equinoxOLI.org> --- .../app/staff/circ/patron/summary.component.html | 79 ++++++++++++++-------- .../src/app/staff/circ/patron/summary.component.ts | 40 +++++++++++ .../src/app/staff/share/circ/grid.component.html | 13 +++- .../eg2/src/app/staff/share/circ/grid.component.ts | 14 ++++ .../sql/Pg/upgrade/XXXX.data.angular-patron.sql | 2 + 5 files changed, 116 insertions(+), 32 deletions(-) diff --git a/Open-ILS/src/eg2/src/app/staff/circ/patron/summary.component.html b/Open-ILS/src/eg2/src/app/staff/circ/patron/summary.component.html index 47081789ca..32f773b156 100644 --- a/Open-ILS/src/eg2/src/app/staff/circ/patron/summary.component.html +++ b/Open-ILS/src/eg2/src/app/staff/circ/patron/summary.component.html @@ -1,13 +1,14 @@ <div class="patron-summary-container"> - <h3 *ngIf="context.patron" class="font-weight-bold" i18n> - {{patronService.namePart(context.patron, 'family_name')}}, - {{patronService.namePart(context.patron, 'first_given_name')}} - {{patronService.namePart(context.patron, 'second_given_name')}} + <h3 *ngIf="patron()" class="font-weight-bold" i18n> + {{patronService.namePart(patron(), 'family_name')}}, + {{patronService.namePart(patron(), 'first_given_name')}} + {{patronService.namePart(patron(), 'second_given_name')}} </h3> - <div class="row mb-1 alert alert-danger p-0" *ngIf="context.alerts.accountExpiresSoon"> + <div class="row mb-1 alert alert-danger p-0" + *ngIf="context.alerts.accountExpiresSoon"> <div class="col-lg-12" i18n> Patron account will expire soon. Please renew. </div> @@ -15,43 +16,43 @@ <div class="row mb-1"> <div class="col-lg-5" i18n>Profile</div> - <div class="col-lg-7">{{context.patron.profile().name()}}</div> + <div class="col-lg-7">{{patron().profile().name()}}</div> </div> <div class="row mb-1"> <div class="col-lg-5" i18n>Home Library</div> - <div class="col-lg-7">{{context.orgSn(context.patron.home_ou())}}</div> + <div class="col-lg-7">{{context.orgSn(patron().home_ou())}}</div> </div> <div class="row mb-1"> <div class="col-lg-5" i18n>Net Access</div> - <div class="col-lg-7">{{context.patron.net_access_level().name()}}</div> + <div class="col-lg-7">{{patron().net_access_level().name()}}</div> </div> <div class="row mb-1"> <div class="col-lg-5" i18n>Date of Birth</div> - <div class="col-lg-7">{{context.patron.dob() | date:'shortDate'}}</div> + <div class="col-lg-7">{{patron().dob() | date:'shortDate'}}</div> </div> <div class="row mb-1"> <div class="col-lg-5" i18n>Parent/Guardian</div> - <div class="col-lg-7">{{context.patron.guardian()}}</div> + <div class="col-lg-7">{{patron().guardian()}}</div> </div> <div class="row mb-1"> <div class="col-lg-5" i18n>Last Activity</div> <div class="col-lg-7"> - <ng-container *ngIf="context.patron.usr_activity()[0]"> - {{context.patron.usr_activity()[0].event_time() | date:'shortDate'}} + <ng-container *ngIf="patron().usr_activity()[0]"> + {{patron().usr_activity()[0].event_time() | date:'shortDate'}} </ng-container> </div> </div> <div class="row mb-1"> <div class="col-lg-5" i18n>Last Updated</div> - <div class="col-lg-7">{{context.patron.last_update_time() | date:'shortDate'}}</div> + <div class="col-lg-7">{{patron().last_update_time() | date:'shortDate'}}</div> </div> <div class="row mb-1"> <div class="col-lg-5" i18n>Create Date</div> - <div class="col-lg-7">{{context.patron.create_date() | date:'shortDate'}}</div> + <div class="col-lg-7">{{patron().create_date() | date:'shortDate'}}</div> </div> <div class="row" [ngClass]="{'alert alert-danger p-0': context.alerts.accountExpired}"> <div class="col-lg-5" i18n>Expire Date</div> - <div class="col-lg-7">{{context.patron.expire_date() | date:'shortDate'}}</div> + <div class="col-lg-7">{{patron().expire_date() | date:'shortDate'}}</div> </div> <hr class="m-1"/> @@ -70,19 +71,23 @@ <div class="col-lg-5" i18n>Items Out</div> <div class="col-lg-7">{{context.patronStats.checkouts.total_out}}</div> </div> - <div class="row mb-1"> + <div class="row mb-1" + [ngClass]="{'alert alert-danger p-0': context.patronStats.checkouts.overdue > 0}"> <div class="col-lg-5" i18n>Overdue</div> <div class="col-lg-7">{{context.patronStats.checkouts.overdue}}</div> </div> - <div class="row mb-1"> + <div class="row mb-1" + [ngClass]="{'alert alert-danger p-0': context.patronStats.checkouts.long_overdue > 0}"> <div class="col-lg-5" i18n>Long Overdue</div> <div class="col-lg-7">{{context.patronStats.checkouts.long_overdue}}</div> </div> - <div class="row mb-1"> + <div class="row mb-1" + [ngClass]="{'alert alert-danger p-0': context.patronStats.checkouts.claims_returned > 0}"> <div class="col-lg-5" i18n>Claimed Returned</div> <div class="col-lg-7">{{context.patronStats.checkouts.claims_returned}}</div> </div> - <div class="row mb-1"> + <div class="row mb-1" + [ngClass]="{'alert alert-danger p-0': context.patronStats.checkouts.lost > 0}"> <div class="col-lg-5" i18n>Lost</div> <div class="col-lg-7">{{context.patronStats.checkouts.lost}}</div> </div> @@ -103,51 +108,65 @@ <div class="row mb-1"> <div class="col-lg-5" i18n>Card</div> <div class="col-lg-7"> - {{context.patron.card() ? context.patron.card().barcode() : ''}} + {{patron().card() ? patron().card().barcode() : ''}} </div> </div> <div class="row mb-1"> <div class="col-lg-5" i18n>Username</div> - <div class="col-lg-7">{{context.patron.usrname()}}</div> + <div class="col-lg-7">{{patron().usrname()}}</div> </div> <div class="row mb-1"> <div class="col-lg-5" i18n>Day Phone</div> - <div class="col-lg-7">{{context.patron.day_phone()}}</div> + <div class="col-lg-7">{{patron().day_phone()}}</div> </div> <div class="row mb-1"> <div class="col-lg-5" i18n>Evening Phone</div> - <div class="col-lg-7">{{context.patron.evening_phone()}}</div> + <div class="col-lg-7">{{patron().evening_phone()}}</div> </div> <div class="row mb-1"> <div class="col-lg-5" i18n>Other Phone</div> - <div class="col-lg-7">{{context.patron.other_phone()}}</div> + <div class="col-lg-7">{{patron().other_phone()}}</div> </div> <div class="row mb-1"> <div class="col-lg-5" i18n>ID1 </div> - <div class="col-lg-7">{{context.patron.ident_value()}}</div> + <div class="col-lg-7">{{patron().ident_value()}}</div> </div> <div class="row mb-1"> <div class="col-lg-5" i18n>ID2</div> - <div class="col-lg-7">{{context.patron.ident_value2()}}</div> + <div class="col-lg-7">{{patron().ident_value2()}}</div> </div> <div class="row mb-1"> <div class="col-lg-5" i18n>Email</div> <div class="col-lg-7"> <!-- TODO: mailto link --> - {{context.patron.email()}} + {{patron().email()}} </div> </div> <hr class="m-1"/> - <div class="row mb-1" *ngFor="let addr of context.patron.addresses()"> + <div class="row mb-1" *ngFor="let addr of patron().addresses()"> <div class="col-lg-12"> <fieldset> - <legend i18n>{{addr.address_type()}}</legend><!-- todo --> + <legend class="d-flex" [ngClass]="{'alert alert-danger p-0': addr.valid() == 'f'}"> + <div class="flex-1">{{addr.address_type()}}</div> + <div> + <a class="mr-2" href="javascript:;" + (click)="copyAddress(addr)" i18n>copy</a> + <a class="mr-2" href="javascript:;" + (click)="printAddress(addr)" i18n>print</a> + </div> + </legend> <div i18n>{{addr.street1()}} {{addr.street2()}}</div> <div i18n>{{addr.city()}}, {{addr.state()}} {{addr.post_code()}}</div> </fieldset> - <!-- todo textarea for copy --> + + <!-- hidden textare used only for copying the text --> + <textarea id="patron-address-copy-{{addr.id()}}" rows="2" + style="visibility:hidden"> +{{patron().first_given_name()}} {{patron().second_given_name()}} {{patron().family_name()}} +{{addr.street1()}} {{addr.street2()}} +{{addr.city()}}, {{addr.state()}} {{addr.post_code()}}</textarea> </div> </div> </div> diff --git a/Open-ILS/src/eg2/src/app/staff/circ/patron/summary.component.ts b/Open-ILS/src/eg2/src/app/staff/circ/patron/summary.component.ts index aac3c49025..dd1a830a83 100644 --- a/Open-ILS/src/eg2/src/app/staff/circ/patron/summary.component.ts +++ b/Open-ILS/src/eg2/src/app/staff/circ/patron/summary.component.ts @@ -2,9 +2,11 @@ import {Component, OnInit, Input} from '@angular/core'; import {Router, ActivatedRoute, ParamMap} from '@angular/router'; import {NgbNav, NgbNavChangeEvent} from '@ng-bootstrap/ng-bootstrap'; import {OrgService} from '@eg/core/org.service'; +import {IdlObject} from '@eg/core/idl.service'; import {NetService} from '@eg/core/net.service'; import {PatronService} from '@eg/staff/share/patron/patron.service'; import {PatronContextService} from './patron.service'; +import {PrintService} from '@eg/share/print/print.service'; @Component({ templateUrl: 'summary.component.html', @@ -16,11 +18,49 @@ export class SummaryComponent implements OnInit { constructor( private org: OrgService, private net: NetService, + private printer: PrintService, public patronService: PatronService, public context: PatronContextService ) {} ngOnInit() { } + + patron(): IdlObject { + return this.context.patron; + } + + printAddress(addr: IdlObject) { + this.printer.print({ + templateName: 'patron_address', + contextData: { + patron: this.context.patron, + address: addr + }, + printContext: 'default' + }); + } + + copyAddress(addr: IdlObject) { + // Note navigator.clipboard requires special permissions. + // This is hinky, but gets the job done without the perms. + + const node = document.getElementById( + `patron-address-copy-${addr.id()}`) as HTMLTextAreaElement; + + // Un-hide the textarea just long enough to copy its data. + // Using node.style instead of *ngIf in hopes it + // will be quicker, so the user never sees the textarea. + node.style.visibility = 'visible'; + node.focus(); + node.select(); + + if (!document.execCommand('copy')) { + console.error('Copy command failed'); + } + + node.style.visibility = 'hidden'; + } + } diff --git a/Open-ILS/src/eg2/src/app/staff/share/circ/grid.component.html b/Open-ILS/src/eg2/src/app/staff/share/circ/grid.component.html index 28353aecee..5a79e40319 100644 --- a/Open-ILS/src/eg2/src/app/staff/share/circ/grid.component.html +++ b/Open-ILS/src/eg2/src/app/staff/share/circ/grid.component.html @@ -39,8 +39,7 @@ [useLocalSort]="true" [cellTextGenerator]="cellTextGenerator"> <eg-grid-toolbar-action - i18n-group group="View" i18n-label label="Print Item Receipt(s)" - (onClick)="printReceipts($event)"> + i18n-label label="Print Item Receipt(s)" (onClick)="printReceipts($event)"> </eg-grid-toolbar-action> <eg-grid-toolbar-action @@ -97,6 +96,16 @@ (onClick)="renewWithDate($event)"> </eg-grid-toolbar-action> + <eg-grid-toolbar-action group="Show" i18n-group + i18n-label label="Show Last Few Circulation" (onClick)="showRecentCircs($event)"> + </eg-grid-toolbar-action> + + <eg-grid-toolbar-action group="Show" i18n-group + i18n-label label="Show Triggered Events" (onClick)="showTriggeredEvents($event)"> + </eg-grid-toolbar-action> + + <!-- Columns =========================================== --> + <eg-grid-column [index]="true" path="index" [hidden]="true" label="Row Index" i18n-label></eg-grid-column> diff --git a/Open-ILS/src/eg2/src/app/staff/share/circ/grid.component.ts b/Open-ILS/src/eg2/src/app/staff/share/circ/grid.component.ts index 59b57d9029..8b79cbae9b 100644 --- a/Open-ILS/src/eg2/src/app/staff/share/circ/grid.component.ts +++ b/Open-ILS/src/eg2/src/app/staff/share/circ/grid.component.ts @@ -604,5 +604,19 @@ export class CircGridComponent implements OnInit { } ); } + + showRecentCircs(rows: CircGridEntry[]) { + const copyId = this.getCopyIds(rows)[0]; + if (copyId) { + window.open('/eg/staff/cat/item/' + copyId + '/circ_list'); + } + } + + showTriggeredEvents(rows: CircGridEntry[]) { + const copyId = this.getCopyIds(rows)[0]; + if (copyId) { + window.open('/eg/staff/cat/item/' + copyId + '/triggered_events'); + } + } } diff --git a/Open-ILS/src/sql/Pg/upgrade/XXXX.data.angular-patron.sql b/Open-ILS/src/sql/Pg/upgrade/XXXX.data.angular-patron.sql index 0a7457f0dd..4a713c3e45 100644 --- a/Open-ILS/src/sql/Pg/upgrade/XXXX.data.angular-patron.sql +++ b/Open-ILS/src/sql/Pg/upgrade/XXXX.data.angular-patron.sql @@ -57,6 +57,8 @@ UPDATE config.print_template SET template = $TEMPLATE$ </div> $TEMPLATE$ WHERE name = 'items_out'; +UPDATE config.print_template SET active = TRUE WHERE name = 'patron_address'; + COMMIT; -- 2.11.0