fix: library account missing ready for pickup

Closes #330
This commit is contained in:
Jovan Krunić
2022-11-11 15:00:34 +00:00
committed by Rainer Killinger
parent 42b860e417
commit e504d8cf6d
12 changed files with 131 additions and 91 deletions

View File

@@ -35,7 +35,7 @@
<ion-icon name="account_circle" slot="start"></ion-icon
>{{ 'library.account.pages.profile.title' | translate | titlecase }}
</ion-item>
<ion-item [routerLink]="['holds-and-reservations']">
<ion-item [routerLink]="['holds']">
<ion-icon name="collections_bookmark" slot="start"></ion-icon
>{{ 'library.account.pages.holds.title' | translate | titlecase }}
</ion-item>

View File

@@ -1,5 +1,5 @@
import {Component} from '@angular/core';
import {DocumentAction, PAIADocument} from '../../types';
import {DocumentAction, PAIADocument, PAIADocumentStatus} from '../../types';
import {LibraryAccountService} from '../library-account.service';
@Component({
@@ -27,8 +27,9 @@ export class CheckedOutPageComponent {
async fetchItems() {
try {
this.checkedOutItems = undefined;
this.checkedOutItems =
await this.libraryAccountService.getCheckedOutItems();
this.checkedOutItems = await this.libraryAccountService.getFilteredItems([
PAIADocumentStatus.Held,
]);
} catch {
await this.libraryAccountService.handleError();
this.checkedOutItems = [];

View File

@@ -1,52 +0,0 @@
<ion-header>
<ion-toolbar color="primary" mode="ios">
<ion-buttons slot="start">
<ion-back-button></ion-back-button>
</ion-buttons>
<ion-title>{{
'library.account.pages.holds.title' | translate | titlecase
}}</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-segment
(ionChange)="segmentChanged($event)"
[value]="paiaDocumentStatus.Ordered"
mode="md"
>
<ion-segment-button [value]="paiaDocumentStatus.Ordered">
<ion-label>{{
'library.account.pages.holds.holds' | translate
}}</ion-label>
</ion-segment-button>
<ion-segment-button [value]="paiaDocumentStatus.Reserved">
<ion-label>{{
'library.account.pages.holds.reservations' | translate
}}</ion-label>
</ion-segment-button>
</ion-segment>
<ion-list *ngIf="paiaDocuments && paiaDocuments.length > 0; else fallback">
<stapps-paia-item
*ngFor="let hold of paiaDocuments"
[item]="hold"
[propertiesToShow]="['label']"
(documentAction)="onDocumentAction($event)"
listName="holds"
>
</stapps-paia-item>
</ion-list>
<ng-template #fallback>
<stapps-skeleton-list-item
hideThumbnail="true"
*ngIf="!paiaDocuments; else nothingFound"
></stapps-skeleton-list-item>
<ng-template #nothingFound>
<ion-label
*ngIf="paiaDocuments && paiaDocuments.length === 0"
class="centeredMessageContainer"
>
{{ 'search.nothing_found' | translate | titlecase }}
</ion-label>
</ng-template>
</ng-template>
</ion-content>

View File

@@ -2,34 +2,45 @@ import {Component} from '@angular/core';
import {DocumentAction, PAIADocument, PAIADocumentStatus} from '../../types';
import {LibraryAccountService} from '../library-account.service';
type Segment = 'orders' | 'reservations';
@Component({
selector: 'app-holds-and-reservations',
templateUrl: './holds-and-reservations-page.html',
styleUrls: ['./holds-and-reservations-page.scss'],
selector: 'stapps-holds',
templateUrl: './holds-page.html',
styleUrls: ['./holds-page.scss'],
})
export class HoldsAndReservationsPageComponent {
export class HoldsPageComponent {
paiaDocuments?: PAIADocument[];
paiaDocumentStatus = PAIADocumentStatus;
activeSegment: Segment = 'orders';
constructor(private readonly libraryAccountService: LibraryAccountService) {}
async ionViewWillEnter(): Promise<void> {
await this.fetchItems();
await this.fetchItems(this.activeSegment);
}
async fetchItems(status: PAIADocumentStatus = PAIADocumentStatus.Ordered) {
async fetchItems(segment: Segment) {
this.activeSegment = segment;
this.paiaDocuments = undefined;
const itemsStatus =
segment === 'reservations'
? [PAIADocumentStatus.Reserved]
: [PAIADocumentStatus.Ordered, PAIADocumentStatus.Provided];
try {
this.paiaDocuments = await (Number(status) === PAIADocumentStatus.Ordered
? this.libraryAccountService.getHolds()
: this.libraryAccountService.getReservations());
this.paiaDocuments = await this.libraryAccountService.getFilteredItems(
itemsStatus,
);
} catch {
await this.libraryAccountService.handleError();
this.paiaDocuments = [];
}
}
toNumber = Number;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
async segmentChanged(event: any) {
await this.fetchItems(event.detail.value);
@@ -40,6 +51,6 @@ export class HoldsAndReservationsPageComponent {
documentAction,
);
if (answer) await this.fetchItems();
if (answer) await this.fetchItems(this.activeSegment);
}
}

View File

@@ -0,0 +1,81 @@
<ion-header>
<ion-toolbar color="primary" mode="ios">
<ion-buttons slot="start">
<ion-back-button></ion-back-button>
</ion-buttons>
<ion-title>{{
'library.account.pages.holds.title' | translate | titlecase
}}</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-segment
[(ngModel)]="activeSegment"
(ionChange)="segmentChanged($event)"
[value]="'orders'"
mode="md"
>
<ion-segment-button [value]="'orders'">
<ion-label>{{
'library.account.pages.holds.holds' | translate
}}</ion-label>
</ion-segment-button>
<ion-segment-button [value]="'reservations'">
<ion-label>{{
'library.account.pages.holds.reservations' | translate
}}</ion-label>
</ion-segment-button>
</ion-segment>
<ion-list *ngIf="paiaDocuments && paiaDocuments.length > 0; else fallback">
<ng-container [ngSwitch]="activeSegment">
<ng-container *ngSwitchCase="'orders'">
<ng-container *ngFor="let hold of paiaDocuments">
<stapps-paia-item
*ngIf="
toNumber(hold.status) === paiaDocumentStatus.Provided;
else ordered
"
[item]="hold"
[propertiesToShow]="['label', 'storage']"
(documentAction)="onDocumentAction($event)"
listName="holds"
>
</stapps-paia-item>
<ng-template #ordered>
<stapps-paia-item
[item]="hold"
[propertiesToShow]="['label']"
(documentAction)="onDocumentAction($event)"
listName="holds"
>
</stapps-paia-item>
</ng-template>
</ng-container>
</ng-container>
<ng-container *ngSwitchCase="'reservations'">
<stapps-paia-item
*ngFor="let hold of paiaDocuments"
[item]="hold"
[propertiesToShow]="['label']"
(documentAction)="onDocumentAction($event)"
listName="holds"
>
</stapps-paia-item>
</ng-container>
</ng-container>
</ion-list>
<ng-template #fallback>
<stapps-skeleton-list-item
hideThumbnail="true"
*ngIf="!paiaDocuments; else nothingFound"
></stapps-skeleton-list-item>
<ng-template #nothingFound>
<ion-label
*ngIf="paiaDocuments && paiaDocuments.length === 0"
class="centeredMessageContainer"
>
{{ 'search.nothing_found' | translate | titlecase }}
</ion-label>
</ng-template>
</ng-template>
</ion-content>

View File

@@ -125,21 +125,11 @@ export class LibraryAccountService {
return input.split(':').pop();
}
async getHolds() {
async getFilteredItems(documentStatus: PAIADocumentStatus[]) {
return (await this.getItems())?.doc.filter(document => {
return [PAIADocumentStatus.Ordered].includes(Number(document.status));
});
}
async getReservations() {
return (await this.getItems())?.doc.filter(document => {
return [PAIADocumentStatus.Reserved].includes(Number(document.status));
});
}
async getCheckedOutItems() {
return (await this.getItems())?.doc.filter(document => {
return PAIADocumentStatus.Held === Number(document.status);
return documentStatus.includes(
Number(document.status) as PAIADocumentStatus,
);
});
}

View File

@@ -22,7 +22,7 @@ import {TranslateModule} from '@ngx-translate/core';
import {LibraryAccountPageComponent} from './account/account.page';
import {ProfilePageComponent} from './account/profile/profile-page.component';
import {CheckedOutPageComponent} from './account/checked-out/checked-out-page.component';
import {HoldsAndReservationsPageComponent} from './account/holds-and-reservations/holds-and-reservations-page.component';
import {HoldsPageComponent} from './account/holds/holds-page.component';
import {FinesPageComponent} from './account/fines/fines-page.component';
import {PAIAItemComponent} from './account/elements/paia-item/paiaitem.component';
import {FirstLastNamePipe} from './account/first-last-name.pipe';
@@ -54,8 +54,8 @@ const routes: ProtectedRoutes | Routes = [
canActivate: [AuthGuardService],
},
{
path: 'library-account/holds-and-reservations',
component: HoldsAndReservationsPageComponent,
path: 'library-account/holds',
component: HoldsPageComponent,
data: {authProvider: 'paia'},
canActivate: [AuthGuardService],
},
@@ -83,7 +83,7 @@ const routes: ProtectedRoutes | Routes = [
LibraryAccountPageComponent,
ProfilePageComponent,
CheckedOutPageComponent,
HoldsAndReservationsPageComponent,
HoldsPageComponent,
FinesPageComponent,
PAIAItemComponent,
FirstLastNamePipe,

View File

@@ -24,6 +24,12 @@ export interface PAIAPatron {
note?: string;
}
/*
* Document representing a library item received from the HeBIS PAIA service
* TODO: would be good to standardize the items of HeBIS PAIA to match the official PAIA documentation
* e.g. status should be number (0-5), and queue, renewals, reminder should be numbers too
* https://gbv.github.io/paia/paia.html#documents
*/
export interface PAIADocument {
status: string;
item?: string;
@@ -37,6 +43,7 @@ export interface PAIADocument {
duedate?: string;
cancancel?: boolean;
canrenew?: boolean;
storage?: string;
// with locations
condition?: unknown;
}

View File

@@ -187,10 +187,10 @@ export const profilePageSections: SCSection[] = [
...SCSectionLinkConstantValues,
},
{
name: 'Holdings & Reservations',
name: 'Orders & Reservations',
icon: SCIcon`collections_bookmark`,
needsAuth: true,
link: ['/library-account/holds-and-reservations'],
link: ['/library-account/holds'],
translations: {
de: {
name: 'Bestellungen & Vormerkungen',