Skip to content

Commit

Permalink
patrons: implement detail view
Browse files Browse the repository at this point in the history
* Adds detail view.
* Adds link on brief view to patron name.
* Adds patron service.
* Adds translations.
* Fixes facet roles is open by default

Co-Authored-by: Bertrand Zuchuat <bertrand.zuchuat@rero.ch>
  • Loading branch information
Garfield-fr committed Dec 4, 2019
1 parent f8fe3c7 commit 24702bd
Show file tree
Hide file tree
Showing 13 changed files with 286 additions and 93 deletions.
7 changes: 5 additions & 2 deletions projects/admin/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ import { ItemDetailViewComponent } from './record/detail-view/item-detail-view/i
import { ItemAvailabilityComponent } from './record/item-availability/item-availability.component';
import { ItemTransactionComponent } from './record/detail-view/item-detail-view/item-transaction/item-transaction.component';
import { ItemTransactionsComponent } from './record/detail-view/item-detail-view/item-transactions/item-transactions.component';
import { PatronDetailViewComponent } from './record/detail-view/patron-detail-view/patron-detail-view.component';

@NgModule({
declarations: [
Expand Down Expand Up @@ -114,7 +115,8 @@ import { ItemTransactionsComponent } from './record/detail-view/item-detail-view
ItemDetailViewComponent,
ItemAvailabilityComponent,
ItemTransactionComponent,
ItemTransactionsComponent
ItemTransactionsComponent,
PatronDetailViewComponent
],
imports: [
Bootstrap4FrameworkModule,
Expand Down Expand Up @@ -176,7 +178,8 @@ import { ItemTransactionsComponent } from './record/detail-view/item-detail-view
CollapseListComponent,
LibraryComponent,
LocationDetailViewComponent,
ItemDetailViewComponent
ItemDetailViewComponent,
PatronDetailViewComponent
],
bootstrap: [AppComponent]
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,60 +15,38 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import { Component, Input } from '@angular/core';
import { ResultItem, RecordService } from '@rero/ng-core';
import { Component, Input, OnInit } from '@angular/core';
import { ResultItem } from '@rero/ng-core';
import { PatronService } from '../../service/patron.service';

@Component({
selector: 'admin-patrons-brief-view',
template: `
<h5 class="card-title mb-0">{{ record.metadata.last_name }}, {{ record.metadata.first_name }}
<small *ngIf="isPatron()">
<h5 class="card-title mb-0">
<a [routerLink]="['/records', 'patrons', 'detail', record.metadata.pid]">
{{ record.metadata.last_name }}, {{ record.metadata.first_name }}
</a>
<small class="ml-3" *ngIf="isPatron">
<a [routerLink]="['/circulation', 'checkinout']" [queryParams]="{ patron: record.metadata.barcode}">
<i class="fa fa-exchange"></i>
<span translate> Circulation</span>
<i class="fa fa-exchange mr-2"></i>
<span translate>Circulation</span>
</a>
</small>
</h5>
<div class="card-text px-2">
<p class="mb-0">{{ record.metadata.birth_date | dateTranslate:'mediumDate' }} &mdash; {{ record.metadata.city }}</p>
<p class="mb-0">
<a class="text-secondary" (click)="toggleCollapse()" [attr.aria-expanded]="!isCollapsed">
<i class="fa"
[ngClass]="{'fa-caret-down': !isCollapsed, 'fa-caret-right': isCollapsed }" aria-hidden="true">
</i>
<span *ngFor="let role of record.metadata.roles; let isLast=last">
{{ role | translate }}{{isLast ? '' : ', '}}
</span>
</a>
</p>
<ul [collapse]="isCollapsed" class="list-group list-group-flush" id="{{ 'patron-'+record.metadata.pid }}">
<li *ngIf="record.metadata.barcode" class="list-group-item p-0 border-0">
<span translate>Barcode</span>: {{ record.metadata.barcode }}
</li>
<li *ngIf="isLibrarian()" class="list-group-item p-0 border-0">
<span translate>Library</span>: {{ record.metadata.library.name }}
</li>
<li *ngIf="isPatron()" class="list-group-item p-0 border-0">
<span translate>Type</span>: {{ record.metadata.patron_type.name }}
</li>
<li *ngIf="record.metadata.phone" class="list-group-item p-0 border-0">
<span translate>Phone</span>: {{ record.metadata.phone }}
</li>
<li class="list-group-item p-0 border-0">
<span translate>Email</span>: <a href="mailto:{{ record.metadata.email }}">{{ record.metadata.email }}</a>
</li>
<li class="list-group-item p-0 border-0">
<span translate>Street</span>: {{ record.metadata.street }}
</li>
<li class="list-group-item p-0 border-0">
<span translate>City</span>: {{ record.metadata.postal_code }} {{ record.metadata.city }}
</li>
</ul>
<span class="font-weight-bold">
<ng-container *ngIf="record.metadata.roles.length === 1; else roles" translate>Role</ng-container>
<ng-template #roles translate>Roles</ng-template>:
</span>
<span *ngFor="let role of record.metadata.roles; let isLast=last">
{{ role | translate }}{{isLast ? '' : ', '}}
</span>
</div>
`,
styles: []
})
export class PatronsBriefViewComponent implements ResultItem {
export class PatronsBriefViewComponent implements OnInit, ResultItem {

@Input()
record: any;
Expand All @@ -79,50 +57,13 @@ export class PatronsBriefViewComponent implements ResultItem {
@Input()
detailUrl: { link: string, external: boolean };

isCollapsed = true;

constructor(
private recordService: RecordService
) {
}

isPatron() {
if (this.record && this.record.metadata.roles) {
return this.record.metadata.roles.some(role => role === 'patron');
}
return false;
}
constructor(private patronService: PatronService) { }

isLibrarian() {
if (this.record && this.record.metadata.roles) {
return this.record.metadata.roles.some(role => role === 'librarian');
}
return false;
ngOnInit() {
this.patronService.setRecord(this.record);
}

toggleCollapse() {
const isCollapsed = this.isCollapsed;
if (isCollapsed) {
if (this.isPatron()) {
const patronTypePid = this.record.metadata.patron_type.pid;
this.recordService
.getRecord('patron_types', patronTypePid, 1)
.subscribe(data => {
this.record.metadata.patron_type = data.metadata;
this.isCollapsed = !isCollapsed;
});
}
if (this.isLibrarian()) {
const libraryPid = this.record.metadata.library.pid;
this.recordService
.getRecord('libraries', libraryPid, 1)
.subscribe(data => {
this.record.metadata.library = data.metadata;
this.isCollapsed = !isCollapsed;
});
}
} else {
this.isCollapsed = !isCollapsed;
}
get isPatron() {
return this.patronService.hasRole('patron');
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<!--
RERO ILS UI
 Copyright (C) 2019 RERO

 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU Affero General Public License as published by
 the Free Software Foundation, version 3 of the License.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 GNU Affero General Public License for more details.

 You should have received a copy of the GNU Affero General Public License
 along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<ng-container *ngIf="record$ | async as record">
<h1 class="mb-3">{{ record.metadata.last_name }} {{ record.metadata.first_name }}</h1>
<article>
<section class="m-2 p-2">
<!-- BARCODE -->
<dl class="row mb-0" *ngIf="record.metadata.barcode">
<dt class="col-sm-3 offset-sm-2 offset-md-0">
{{ 'Barcode' | translate }}:
</dt>
<dd class="col-sm-7 col-md-8 mb-0">
<a [routerLink]="['/circulation', 'checkinout']" [queryParams]="{ patron: record.metadata.barcode }">{{ record.metadata.barcode }}</a>
</dd>
</dl>
<!-- TYPE -->
<dl class="row mb-0" *ngIf="isPatron">
<dt class="col-sm-3 offset-sm-2 offset-md-0">
{{ 'Type' | translate }}:
</dt>
<dd class="col-sm-7 col-md-8 mb-0">
{{ record.metadata.patron_type.pid | getRecord: 'patron_types' : 'field' : 'name' | async }}
</dd>
</dl>
<!-- TYPE -->
<dl class="row mb-0" *ngIf="isLibrarian">
<dt class="col-sm-3 offset-sm-2 offset-md-0">
{{ 'Library' | translate }}:
</dt>
<dd class="col-sm-7 col-md-8 mb-0">
{{ record.metadata.library.pid | getRecord: 'libraries' : 'field' : 'name' | async }}
</dd>
</dl>
<!-- PHONE -->
<dl class="row mb-0" *ngIf="record.metadata.phone">
<dt class="col-sm-3 offset-sm-2 offset-md-0">
{{ 'Phone' | translate }}:
</dt>
<dd class="col-sm-7 col-md-8 mb-0">
{{ record.metadata.phone }}
</dd>
</dl>
<!-- EMAIL -->
<dl class="row mb-0">
<dt class="col-sm-3 offset-sm-2 offset-md-0">
{{ 'Email' | translate }}:
</dt>
<dd class="col-sm-7 col-md-8 mb-0">
{{ record.metadata.email }}
</dd>
</dl>
<!-- STREET -->
<dl class="row mb-0">
<dt class="col-sm-3 offset-sm-2 offset-md-0">
{{ 'Street' | translate }}:
</dt>
<dd class="col-sm-7 col-md-8 mb-0">
{{ record.metadata.street }}
</dd>
</dl>
<!-- CITY -->
<dl class="row mb-0">
<dt class="col-sm-3 offset-sm-2 offset-md-0">
{{ 'City' | translate }}:
</dt>
<dd class="col-sm-7 col-md-8 mb-0">
{{ record.metadata.postal_code }} {{ record.metadata.city }}
</dd>
</dl>
<!-- ROLES -->
<dl class="row mb-0">
<dt class="col-sm-3 offset-sm-2 offset-md-0">
<ng-container *ngIf="record.metadata.roles.length === 1; else roles" translate>Role</ng-container>
<ng-template #roles translate>Roles</ng-template>:
</dt>
<dd class="col-sm-7 col-md-8 mb-0">
<ng-container *ngFor="let role of record.metadata.roles; let last=last">
{{ role | translate }}{{ last ? '' : ', ' }}
</ng-container>
</dd>
</dl>
</section>
</article>
</ng-container>
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* RERO ILS UI
* Copyright (C) 2019 RERO
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { Component, OnInit } from '@angular/core';
import { DetailRecord } from '@rero/ng-core/lib/record/detail/view/detail-record';
import { Observable } from 'rxjs';
import { PatronService } from '../../../service/patron.service';

@Component({
selector: 'admin-patron-detail-view',
templateUrl: './patron-detail-view.component.html'
})
export class PatronDetailViewComponent implements OnInit, DetailRecord {

record$: Observable<any>;

record: any;

type: string;

constructor(private patronService: PatronService) { }

ngOnInit() {
this.record$.subscribe(record => {
this.record = record;
this.patronService.setRecord(record);
});
}

get isPatron() {
return this.patronService.hasRole('patron');
}

get isLibrarian() {
return this.patronService.hasRole('librarian');
}
}
28 changes: 28 additions & 0 deletions projects/admin/src/app/service/patron.service.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* RERO ILS UI
* Copyright (C) 2019 RERO
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { TestBed } from '@angular/core/testing';

import { PatronService } from './patron.service';

describe('PatronService', () => {
beforeEach(() => TestBed.configureTestingModule({}));

it('should be created', () => {
const service: PatronService = TestBed.get(PatronService);
expect(service).toBeTruthy();
});
});
40 changes: 40 additions & 0 deletions projects/admin/src/app/service/patron.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* RERO ILS UI
* Copyright (C) 2019 RERO
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { Injectable } from '@angular/core';

@Injectable({
providedIn: 'root'
})
export class PatronService {

private _patron: any;

/**
* Set Patron record
* @param patron - patron record
*/
setRecord(patron: any) {
this._patron = patron.metadata;
}

hasRole(patronRole: string) {
if (this._patron && this._patron.roles) {
return this._patron.roles.some((role: string) => role === patronRole);
}
return false;
}
}
Loading

0 comments on commit 24702bd

Please sign in to comment.