From c7b6977f9c19ed49d00b3cf5d0bc4f62c38f1394 Mon Sep 17 00:00:00 2001 From: Bill Erickson Date: Wed, 12 Aug 2020 18:18:13 -0400 Subject: [PATCH] LPXXX Patron UI WIP Signed-off-by: Bill Erickson --- .../app/staff/circ/patron/checkout.component.html | 2 + .../app/staff/circ/patron/checkout.component.ts | 25 +++++ .../src/app/staff/circ/patron/patron-context.ts | 12 --- ...{patrons.component.css => patron.component.css} | 1 + ...atrons.component.html => patron.component.html} | 23 ++++- .../src/app/staff/circ/patron/patron.component.ts | 103 +++++++++++++++++++ .../patron/{patrons.module.ts => patron.module.ts} | 11 +- .../src/app/staff/circ/patron/patron.service.ts | 46 +++++++++ .../src/app/staff/circ/patron/patrons.component.ts | 93 ----------------- .../src/app/staff/circ/patron/routing.module.ts | 8 +- .../app/staff/circ/patron/summary-component.css | 6 ++ .../app/staff/circ/patron/summary.component.html | 114 ++++++++++++++++++++- .../src/app/staff/circ/patron/summary.component.ts | 15 ++- .../src/eg2/src/app/staff/circ/routing.module.ts | 2 +- 14 files changed, 337 insertions(+), 124 deletions(-) create mode 100644 Open-ILS/src/eg2/src/app/staff/circ/patron/checkout.component.html create mode 100644 Open-ILS/src/eg2/src/app/staff/circ/patron/checkout.component.ts delete mode 100644 Open-ILS/src/eg2/src/app/staff/circ/patron/patron-context.ts rename Open-ILS/src/eg2/src/app/staff/circ/patron/{patrons.component.css => patron.component.css} (85%) rename Open-ILS/src/eg2/src/app/staff/circ/patron/{patrons.component.html => patron.component.html} (66%) create mode 100644 Open-ILS/src/eg2/src/app/staff/circ/patron/patron.component.ts rename Open-ILS/src/eg2/src/app/staff/circ/patron/{patrons.module.ts => patron.module.ts} (76%) create mode 100644 Open-ILS/src/eg2/src/app/staff/circ/patron/patron.service.ts delete mode 100644 Open-ILS/src/eg2/src/app/staff/circ/patron/patrons.component.ts create mode 100644 Open-ILS/src/eg2/src/app/staff/circ/patron/summary-component.css diff --git a/Open-ILS/src/eg2/src/app/staff/circ/patron/checkout.component.html b/Open-ILS/src/eg2/src/app/staff/circ/patron/checkout.component.html new file mode 100644 index 0000000000..d6add2b645 --- /dev/null +++ b/Open-ILS/src/eg2/src/app/staff/circ/patron/checkout.component.html @@ -0,0 +1,2 @@ + +CHECKOUT diff --git a/Open-ILS/src/eg2/src/app/staff/circ/patron/checkout.component.ts b/Open-ILS/src/eg2/src/app/staff/circ/patron/checkout.component.ts new file mode 100644 index 0000000000..e300bbe94e --- /dev/null +++ b/Open-ILS/src/eg2/src/app/staff/circ/patron/checkout.component.ts @@ -0,0 +1,25 @@ +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 {NetService} from '@eg/core/net.service'; +import {PatronService} from '@eg/staff/share/patron/patron.service'; +import {PatronManagerService} from './patron.service'; + +@Component({ + templateUrl: 'checkout.component.html', + selector: 'eg-patron-checkout' +}) +export class CheckoutComponent implements OnInit { + + constructor( + private org: OrgService, + private net: NetService, + public patronService: PatronService, + public context: PatronManagerService + ) {} + + ngOnInit() { + } +} + diff --git a/Open-ILS/src/eg2/src/app/staff/circ/patron/patron-context.ts b/Open-ILS/src/eg2/src/app/staff/circ/patron/patron-context.ts deleted file mode 100644 index d88e4215bb..0000000000 --- a/Open-ILS/src/eg2/src/app/staff/circ/patron/patron-context.ts +++ /dev/null @@ -1,12 +0,0 @@ -import {IdlObject} from '@eg/core/idl.service'; - -export class PatronContext { - - patron: IdlObject; - - setPatron(patron: IdlObject) { - this.patron = patron; - } -} - - diff --git a/Open-ILS/src/eg2/src/app/staff/circ/patron/patrons.component.css b/Open-ILS/src/eg2/src/app/staff/circ/patron/patron.component.css similarity index 85% rename from Open-ILS/src/eg2/src/app/staff/circ/patron/patrons.component.css rename to Open-ILS/src/eg2/src/app/staff/circ/patron/patron.component.css index 1c10d8ac94..8897ed1234 100644 --- a/Open-ILS/src/eg2/src/app/staff/circ/patron/patrons.component.css +++ b/Open-ILS/src/eg2/src/app/staff/circ/patron/patron.component.css @@ -1,6 +1,7 @@ .patron-content-pane { margin-top: 10px; + padding-top: 10px; position: fixed; height: 100%; overflow-y: auto; diff --git a/Open-ILS/src/eg2/src/app/staff/circ/patron/patrons.component.html b/Open-ILS/src/eg2/src/app/staff/circ/patron/patron.component.html similarity index 66% rename from Open-ILS/src/eg2/src/app/staff/circ/patron/patrons.component.html rename to Open-ILS/src/eg2/src/app/staff/circ/patron/patron.component.html index f3f3866d4c..237fe99743 100644 --- a/Open-ILS/src/eg2/src/app/staff/circ/patron/patrons.component.html +++ b/Open-ILS/src/eg2/src/app/staff/circ/patron/patron.component.html @@ -2,33 +2,46 @@
- +

{{patronService.namePart(context.patron, 'family_name')}}, {{patronService.namePart(context.patron, 'first_given_name')}} {{patronService.namePart(context.patron, 'second_given_name')}} - +

-
+
- +
diff --git a/Open-ILS/src/eg2/src/app/staff/circ/patron/patron.component.ts b/Open-ILS/src/eg2/src/app/staff/circ/patron/patron.component.ts new file mode 100644 index 0000000000..8894b1bede --- /dev/null +++ b/Open-ILS/src/eg2/src/app/staff/circ/patron/patron.component.ts @@ -0,0 +1,103 @@ +import {Component, OnInit, AfterViewInit} from '@angular/core'; +import {Router, ActivatedRoute, ParamMap} from '@angular/router'; +import {NgbNav, NgbNavChangeEvent} from '@ng-bootstrap/ng-bootstrap'; +import {NetService} from '@eg/core/net.service'; +import {AuthService} from '@eg/core/auth.service'; +import {PatronService} from '@eg/staff/share/patron/patron.service'; +import {PatronManagerService} from './patron.service'; +import {PatronSearchComponent} from '@eg/staff/share/patron/search.component'; + +@Component({ + templateUrl: 'patron.component.html', + styleUrls: ['patron.component.css'] +}) +export class PatronComponent implements OnInit, AfterViewInit { + + patronTab = 'search'; + patronId: number; + showSummary = true; + viewInitDone = false; + + constructor( + private router: Router, + private route: ActivatedRoute, + private net: NetService, + private auth: AuthService, + public patronService: PatronService, + public context: PatronManagerService + ) {} + + ngOnInit() { + this.watchForTabChange(); + } + + watchForTabChange() { + this.route.paramMap.subscribe((params: ParamMap) => { + this.patronTab = params.get('tab') || 'search'; + this.patronId = +params.get('id'); + + if (!this.patronId || ( + this.context.patron && + this.context.patron.id() === this.patronId)) { + return; + } + + this.context.loadPatron(this.patronId); + }); + } + + // Trick that allows us to set a value for ngbNavOutlet, whose + // component is not avilable until after view init, without + // firing "expression changed after check" errors. + ngAfterViewInit() { + setTimeout(() => this.viewInitDone = true); + } + + beforeTabChange(evt: NgbNavChangeEvent) { + // tab will change with route navigation. + evt.preventDefault(); + + this.patronTab = evt.nextId; + this.routeToTab(); + } + + routeToTab() { + let url = '/staff/circ/patron/'; + + switch (this.patronTab) { + case 'search': + case 'bcsearch': + url += this.patronTab; + break; + default: + url += `${this.patronId}/${this.patronTab}`; + } + + this.router.navigate([url]); + } + + // Patron row single-clicked in the grid. Load the patron without + // leaving the search tab. + patronsClicked(rows: any[]) { + if (rows.length !== 1) { return; } + + const id = rows[0].id(); + if (id !== this.patronId) { + this.patronId = id; + this.context.loadPatron(id); + return; + } + } + + // Route to checkout tab for selected patron. + patronsSelected(rows: any[]) { + if (rows.length !== 1) { return; } + + const id = rows[0].id(); + this.patronId = id; + this.patronTab = 'checkout'; + this.routeToTab(); + } + +} + diff --git a/Open-ILS/src/eg2/src/app/staff/circ/patron/patrons.module.ts b/Open-ILS/src/eg2/src/app/staff/circ/patron/patron.module.ts similarity index 76% rename from Open-ILS/src/eg2/src/app/staff/circ/patron/patrons.module.ts rename to Open-ILS/src/eg2/src/app/staff/circ/patron/patron.module.ts index 8b4857aada..d4396e39cc 100644 --- a/Open-ILS/src/eg2/src/app/staff/circ/patron/patrons.module.ts +++ b/Open-ILS/src/eg2/src/app/staff/circ/patron/patron.module.ts @@ -6,14 +6,17 @@ import {HoldsModule} from '@eg/staff/share/holds/holds.module'; import {HoldingsModule} from '@eg/staff/share/holdings/holdings.module'; import {BookingModule} from '@eg/staff/share/booking/booking.module'; import {PatronModule} from '@eg/staff/share/patron/patron.module'; -import {PatronsComponent} from './patrons.component'; +import {PatronManagerService} from './patron.service'; +import {PatronComponent} from './patron.component'; import {SummaryComponent} from './summary.component'; +import {CheckoutComponent} from './checkout.component'; import {BcSearchComponent} from './bcsearch.component'; @NgModule({ declarations: [ - PatronsComponent, + PatronComponent, SummaryComponent, + CheckoutComponent, BcSearchComponent ], imports: [ @@ -26,9 +29,9 @@ import {BcSearchComponent} from './bcsearch.component'; PatronRoutingModule ], providers: [ - // PatronService + PatronManagerService ] }) -export class PatronsModule {} +export class PatronManagerModule {} diff --git a/Open-ILS/src/eg2/src/app/staff/circ/patron/patron.service.ts b/Open-ILS/src/eg2/src/app/staff/circ/patron/patron.service.ts new file mode 100644 index 0000000000..258a0e7800 --- /dev/null +++ b/Open-ILS/src/eg2/src/app/staff/circ/patron/patron.service.ts @@ -0,0 +1,46 @@ +import {Injectable} from '@angular/core'; +import {IdlObject} from '@eg/core/idl.service'; +import {NetService} from '@eg/core/net.service'; +import {AuthService} from '@eg/core/auth.service'; +import {PatronService} from '@eg/staff/share/patron/patron.service'; + +const PATRON_FLESH_FIELDS = [ + 'card', + 'cards', + 'settings', + 'standing_penalties', + 'addresses', + 'billing_address', + 'mailing_address', + 'stat_cat_entries', + 'waiver_entries', + 'usr_activity', + 'notes', + 'profile', + 'net_access_level', + 'ident_type', + 'ident_type2', + 'groups' +]; + +@Injectable() +export class PatronManagerService { + + patron: IdlObject; + + constructor( + private net: NetService, + private auth: AuthService, + public patronService: PatronService + ) {} + + loadPatron(id: number): Promise { + return this.net.request( + 'open-ils.actor', + 'open-ils.actor.user.fleshed.retrieve', + this.auth.token(), id, PATRON_FLESH_FIELDS + ).toPromise().then(patron => this.patron = patron); + } +} + + diff --git a/Open-ILS/src/eg2/src/app/staff/circ/patron/patrons.component.ts b/Open-ILS/src/eg2/src/app/staff/circ/patron/patrons.component.ts deleted file mode 100644 index d74310ce98..0000000000 --- a/Open-ILS/src/eg2/src/app/staff/circ/patron/patrons.component.ts +++ /dev/null @@ -1,93 +0,0 @@ -import {Component, OnInit} from '@angular/core'; -import {Router, ActivatedRoute, ParamMap} from '@angular/router'; -import {NgbNav, NgbNavChangeEvent} from '@ng-bootstrap/ng-bootstrap'; -import {NetService} from '@eg/core/net.service'; -import {AuthService} from '@eg/core/auth.service'; -import {PatronService} from '@eg/staff/share/patron/patron.service'; -import {PatronContext} from './patron-context'; -import {PatronSearchComponent} from '@eg/staff/share/patron/search.component'; - -const PATRON_FLESH_FIELDS = [ - 'card', - 'cards', - 'settings', - 'standing_penalties', - 'addresses', - 'billing_address', - 'mailing_address', - 'stat_cat_entries', - 'waiver_entries', - 'usr_activity', - 'notes', - 'profile', - 'net_access_level', - 'ident_type', - 'ident_type2', - 'groups' -]; - -@Component({ - templateUrl: 'patrons.component.html', - styleUrls: ['patrons.component.css'] -}) -export class PatronsComponent implements OnInit { - - context: PatronContext; - patronTab = 'search'; - patronId: number; - - showSummary = true; - - constructor( - private router: Router, - private route: ActivatedRoute, - private net: NetService, - private auth: AuthService, - public patronService: PatronService - ) {} - - ngOnInit() { - this.route.paramMap.subscribe((params: ParamMap) => { - this.patronTab = params.get('tab') || 'search'; - this.patronId = +params.get('id'); - this.context = new PatronContext(); - - if (this.patronId) { this.loadPatron(); } - }); - } - - beforeTabChange(evt: NgbNavChangeEvent) { - // tab will change with route navigation. - evt.preventDefault(); - - this.patronTab = evt.nextId; - this.routeToTab(); - } - - routeToTab() { - const url = - `/staff/circ/patron/${this.patronId}/${this.patronTab}`; - - this.router.navigate([url]); - } - - patronsSelected(rows: any[]) { - if (rows.length === 1) { - const id = rows[0].id(); - if (id !== this.patronId) { - this.patronId = id; - this.loadPatron(); - return; - } - } - } - - loadPatron() { - this.net.request( - 'open-ils.actor', - 'open-ils.actor.user.fleshed.retrieve', - this.auth.token(), this.patronId, PATRON_FLESH_FIELDS - ).subscribe(patron => this.context.setPatron(patron)); - } -} - diff --git a/Open-ILS/src/eg2/src/app/staff/circ/patron/routing.module.ts b/Open-ILS/src/eg2/src/app/staff/circ/patron/routing.module.ts index 3b9340460c..cb6c7b2d94 100644 --- a/Open-ILS/src/eg2/src/app/staff/circ/patron/routing.module.ts +++ b/Open-ILS/src/eg2/src/app/staff/circ/patron/routing.module.ts @@ -1,6 +1,6 @@ import {NgModule} from '@angular/core'; import {RouterModule, Routes} from '@angular/router'; -import {PatronsComponent} from './patrons.component'; +import {PatronComponent} from './patron.component'; const routes: Routes = [{ path: '', @@ -8,13 +8,13 @@ const routes: Routes = [{ redirectTo: 'search' }, { path: 'search', - component: PatronsComponent + component: PatronComponent }, { path: 'bcsearch', - component: PatronsComponent + component: PatronComponent }, { path: ':id/:tab', - component: PatronsComponent, + component: PatronComponent, }]; @NgModule({ diff --git a/Open-ILS/src/eg2/src/app/staff/circ/patron/summary-component.css b/Open-ILS/src/eg2/src/app/staff/circ/patron/summary-component.css new file mode 100644 index 0000000000..71ba8a412d --- /dev/null +++ b/Open-ILS/src/eg2/src/app/staff/circ/patron/summary-component.css @@ -0,0 +1,6 @@ + +.patron-summary-container .row:nth-child(odd) { + background-color: rgb(248, 248, 248); +} + + 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 1dc27ce9df..57bd105718 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,2 +1,114 @@ -summary +
+
+
Profile
+
{{context.patron.profile().name()}}
+
+
+
Home Library
+
{{orgSn(context.patron.home_ou())}}
+
+
+
Net Access
+
{{context.patron.net_access_level().name()}}
+
+
+
Date of Birth
+
{{context.patron.dob() | date:'shortDate'}}
+
+
+
Parent/Guardian
+
{{context.patron.guardian()}}
+
+
+
Last Activity
+
+ + {{context.patron.usr_activity()[0].event_time() | date:'shortDate'}} + +
+
+
+
Last Updated
+
{{context.patron.last_update_time() | date:'shortDate'}}
+
+
+
Create Date
+
{{context.patron.create_date() | date:'shortDate'}}
+
+
+
Expire Date
+
{{context.patron.expire_date() | date:'shortDate'}}
+
+ +
+ +
+
Fines Owed
+
XXXX
+
+
+
Items Out
+
XXXX
+
+
+
Overdue
+
XXXX
+
+
+
Long Overdue
+
XXXX
+
+
+
Claimed Returned
+
XXXX
+
+
+
Lost
+
XXXX
+
+
+
Non-Cataloged
+
XXXX
+
+
+
Holds
+
XX / YY
+
+ +
+ +
+
Card
+
XXXXXXXXXX
+
+
+
Username
+
XXXXXXXXXX
+
+
+
Day Phone
+
XXXXXXXXXX
+
+
+
Evening Phone
+
XXXXXXXXXX
+
+
+
Other Phone
+
XXXXXXXXXX
+
+
+
ID1
+
XXXXXXXXXX
+
+
+
ID2
+
XXXXXXXXXX
+
+
+
Email
+
XXXXXXXXXX
+
+ +
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 e7de281180..4381075b51 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 @@ -1,24 +1,31 @@ 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 {NetService} from '@eg/core/net.service'; import {PatronService} from '@eg/staff/share/patron/patron.service'; -import {PatronContext} from './patron-context'; +import {PatronManagerService} from './patron.service'; @Component({ templateUrl: 'summary.component.html', + styleUrls: ['summary-component.css'], selector: 'eg-patron-summary' }) export class SummaryComponent implements OnInit { - @Input() context: PatronContext; - constructor( + private org: OrgService, private net: NetService, - public patronService: PatronService + public patronService: PatronService, + public context: PatronManagerService ) {} ngOnInit() { } + + orgSn(orgId: number): string { + const org = this.org.get(orgId); + return org ? org.shortname() : ''; + } } diff --git a/Open-ILS/src/eg2/src/app/staff/circ/routing.module.ts b/Open-ILS/src/eg2/src/app/staff/circ/routing.module.ts index af4bb91310..fe3d26e3fb 100644 --- a/Open-ILS/src/eg2/src/app/staff/circ/routing.module.ts +++ b/Open-ILS/src/eg2/src/app/staff/circ/routing.module.ts @@ -4,7 +4,7 @@ import {RouterModule, Routes} from '@angular/router'; const routes: Routes = [ { path: 'patron', loadChildren: () => - import('./patron/patrons.module').then(m => m.PatronsModule) + import('./patron/patron.module').then(m => m.PatronManagerModule) } ]; -- 2.11.0