mirror of
https://gitlab.com/openstapps/openstapps.git
synced 2026-01-21 17:12:43 +00:00
committed by
Rainer Killinger
parent
42b860e417
commit
e504d8cf6d
@@ -35,7 +35,7 @@
|
|||||||
<ion-icon name="account_circle" slot="start"></ion-icon
|
<ion-icon name="account_circle" slot="start"></ion-icon
|
||||||
>{{ 'library.account.pages.profile.title' | translate | titlecase }}
|
>{{ 'library.account.pages.profile.title' | translate | titlecase }}
|
||||||
</ion-item>
|
</ion-item>
|
||||||
<ion-item [routerLink]="['holds-and-reservations']">
|
<ion-item [routerLink]="['holds']">
|
||||||
<ion-icon name="collections_bookmark" slot="start"></ion-icon
|
<ion-icon name="collections_bookmark" slot="start"></ion-icon
|
||||||
>{{ 'library.account.pages.holds.title' | translate | titlecase }}
|
>{{ 'library.account.pages.holds.title' | translate | titlecase }}
|
||||||
</ion-item>
|
</ion-item>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import {Component} from '@angular/core';
|
import {Component} from '@angular/core';
|
||||||
import {DocumentAction, PAIADocument} from '../../types';
|
import {DocumentAction, PAIADocument, PAIADocumentStatus} from '../../types';
|
||||||
import {LibraryAccountService} from '../library-account.service';
|
import {LibraryAccountService} from '../library-account.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@@ -27,8 +27,9 @@ export class CheckedOutPageComponent {
|
|||||||
async fetchItems() {
|
async fetchItems() {
|
||||||
try {
|
try {
|
||||||
this.checkedOutItems = undefined;
|
this.checkedOutItems = undefined;
|
||||||
this.checkedOutItems =
|
this.checkedOutItems = await this.libraryAccountService.getFilteredItems([
|
||||||
await this.libraryAccountService.getCheckedOutItems();
|
PAIADocumentStatus.Held,
|
||||||
|
]);
|
||||||
} catch {
|
} catch {
|
||||||
await this.libraryAccountService.handleError();
|
await this.libraryAccountService.handleError();
|
||||||
this.checkedOutItems = [];
|
this.checkedOutItems = [];
|
||||||
|
|||||||
@@ -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>
|
|
||||||
@@ -2,34 +2,45 @@ import {Component} from '@angular/core';
|
|||||||
import {DocumentAction, PAIADocument, PAIADocumentStatus} from '../../types';
|
import {DocumentAction, PAIADocument, PAIADocumentStatus} from '../../types';
|
||||||
import {LibraryAccountService} from '../library-account.service';
|
import {LibraryAccountService} from '../library-account.service';
|
||||||
|
|
||||||
|
type Segment = 'orders' | 'reservations';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-holds-and-reservations',
|
selector: 'stapps-holds',
|
||||||
templateUrl: './holds-and-reservations-page.html',
|
templateUrl: './holds-page.html',
|
||||||
styleUrls: ['./holds-and-reservations-page.scss'],
|
styleUrls: ['./holds-page.scss'],
|
||||||
})
|
})
|
||||||
export class HoldsAndReservationsPageComponent {
|
export class HoldsPageComponent {
|
||||||
paiaDocuments?: PAIADocument[];
|
paiaDocuments?: PAIADocument[];
|
||||||
|
|
||||||
paiaDocumentStatus = PAIADocumentStatus;
|
paiaDocumentStatus = PAIADocumentStatus;
|
||||||
|
|
||||||
|
activeSegment: Segment = 'orders';
|
||||||
|
|
||||||
constructor(private readonly libraryAccountService: LibraryAccountService) {}
|
constructor(private readonly libraryAccountService: LibraryAccountService) {}
|
||||||
|
|
||||||
async ionViewWillEnter(): Promise<void> {
|
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;
|
this.paiaDocuments = undefined;
|
||||||
|
const itemsStatus =
|
||||||
|
segment === 'reservations'
|
||||||
|
? [PAIADocumentStatus.Reserved]
|
||||||
|
: [PAIADocumentStatus.Ordered, PAIADocumentStatus.Provided];
|
||||||
try {
|
try {
|
||||||
this.paiaDocuments = await (Number(status) === PAIADocumentStatus.Ordered
|
this.paiaDocuments = await this.libraryAccountService.getFilteredItems(
|
||||||
? this.libraryAccountService.getHolds()
|
itemsStatus,
|
||||||
: this.libraryAccountService.getReservations());
|
);
|
||||||
} catch {
|
} catch {
|
||||||
await this.libraryAccountService.handleError();
|
await this.libraryAccountService.handleError();
|
||||||
this.paiaDocuments = [];
|
this.paiaDocuments = [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toNumber = Number;
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
async segmentChanged(event: any) {
|
async segmentChanged(event: any) {
|
||||||
await this.fetchItems(event.detail.value);
|
await this.fetchItems(event.detail.value);
|
||||||
@@ -40,6 +51,6 @@ export class HoldsAndReservationsPageComponent {
|
|||||||
documentAction,
|
documentAction,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (answer) await this.fetchItems();
|
if (answer) await this.fetchItems(this.activeSegment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
81
src/app/modules/library/account/holds/holds-page.html
Normal file
81
src/app/modules/library/account/holds/holds-page.html
Normal 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>
|
||||||
@@ -125,21 +125,11 @@ export class LibraryAccountService {
|
|||||||
return input.split(':').pop();
|
return input.split(':').pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
async getHolds() {
|
async getFilteredItems(documentStatus: PAIADocumentStatus[]) {
|
||||||
return (await this.getItems())?.doc.filter(document => {
|
return (await this.getItems())?.doc.filter(document => {
|
||||||
return [PAIADocumentStatus.Ordered].includes(Number(document.status));
|
return documentStatus.includes(
|
||||||
});
|
Number(document.status) as PAIADocumentStatus,
|
||||||
}
|
);
|
||||||
|
|
||||||
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);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import {TranslateModule} from '@ngx-translate/core';
|
|||||||
import {LibraryAccountPageComponent} from './account/account.page';
|
import {LibraryAccountPageComponent} from './account/account.page';
|
||||||
import {ProfilePageComponent} from './account/profile/profile-page.component';
|
import {ProfilePageComponent} from './account/profile/profile-page.component';
|
||||||
import {CheckedOutPageComponent} from './account/checked-out/checked-out-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 {FinesPageComponent} from './account/fines/fines-page.component';
|
||||||
import {PAIAItemComponent} from './account/elements/paia-item/paiaitem.component';
|
import {PAIAItemComponent} from './account/elements/paia-item/paiaitem.component';
|
||||||
import {FirstLastNamePipe} from './account/first-last-name.pipe';
|
import {FirstLastNamePipe} from './account/first-last-name.pipe';
|
||||||
@@ -54,8 +54,8 @@ const routes: ProtectedRoutes | Routes = [
|
|||||||
canActivate: [AuthGuardService],
|
canActivate: [AuthGuardService],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'library-account/holds-and-reservations',
|
path: 'library-account/holds',
|
||||||
component: HoldsAndReservationsPageComponent,
|
component: HoldsPageComponent,
|
||||||
data: {authProvider: 'paia'},
|
data: {authProvider: 'paia'},
|
||||||
canActivate: [AuthGuardService],
|
canActivate: [AuthGuardService],
|
||||||
},
|
},
|
||||||
@@ -83,7 +83,7 @@ const routes: ProtectedRoutes | Routes = [
|
|||||||
LibraryAccountPageComponent,
|
LibraryAccountPageComponent,
|
||||||
ProfilePageComponent,
|
ProfilePageComponent,
|
||||||
CheckedOutPageComponent,
|
CheckedOutPageComponent,
|
||||||
HoldsAndReservationsPageComponent,
|
HoldsPageComponent,
|
||||||
FinesPageComponent,
|
FinesPageComponent,
|
||||||
PAIAItemComponent,
|
PAIAItemComponent,
|
||||||
FirstLastNamePipe,
|
FirstLastNamePipe,
|
||||||
|
|||||||
@@ -24,6 +24,12 @@ export interface PAIAPatron {
|
|||||||
note?: string;
|
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 {
|
export interface PAIADocument {
|
||||||
status: string;
|
status: string;
|
||||||
item?: string;
|
item?: string;
|
||||||
@@ -37,6 +43,7 @@ export interface PAIADocument {
|
|||||||
duedate?: string;
|
duedate?: string;
|
||||||
cancancel?: boolean;
|
cancancel?: boolean;
|
||||||
canrenew?: boolean;
|
canrenew?: boolean;
|
||||||
|
storage?: string;
|
||||||
// with locations
|
// with locations
|
||||||
condition?: unknown;
|
condition?: unknown;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -187,10 +187,10 @@ export const profilePageSections: SCSection[] = [
|
|||||||
...SCSectionLinkConstantValues,
|
...SCSectionLinkConstantValues,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Holdings & Reservations',
|
name: 'Orders & Reservations',
|
||||||
icon: SCIcon`collections_bookmark`,
|
icon: SCIcon`collections_bookmark`,
|
||||||
needsAuth: true,
|
needsAuth: true,
|
||||||
link: ['/library-account/holds-and-reservations'],
|
link: ['/library-account/holds'],
|
||||||
translations: {
|
translations: {
|
||||||
de: {
|
de: {
|
||||||
name: 'Bestellungen & Vormerkungen',
|
name: 'Bestellungen & Vormerkungen',
|
||||||
|
|||||||
@@ -273,7 +273,8 @@
|
|||||||
"title": "Titel",
|
"title": "Titel",
|
||||||
"about": "Mehr Informationen",
|
"about": "Mehr Informationen",
|
||||||
"label": "Signatur",
|
"label": "Signatur",
|
||||||
"endtime": "Zum Abholen bis"
|
"endtime": "Abzuholen bis",
|
||||||
|
"storage": "Abholbereit"
|
||||||
},
|
},
|
||||||
"holds": "Bestellungen",
|
"holds": "Bestellungen",
|
||||||
"reservations": "Vormerkungen"
|
"reservations": "Vormerkungen"
|
||||||
|
|||||||
@@ -268,14 +268,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"holds": {
|
"holds": {
|
||||||
"title": "holds and reservations",
|
"title": "Orders and reservations",
|
||||||
"labels": {
|
"labels": {
|
||||||
"title": "Title",
|
"title": "Title",
|
||||||
"about": "More information",
|
"about": "More information",
|
||||||
"label": "Label",
|
"label": "Shelfmark",
|
||||||
"endtime": "Available for pickup until"
|
"endtime": "Available for pickup until",
|
||||||
|
"storage": "Available for pickup"
|
||||||
},
|
},
|
||||||
"holds": "holds",
|
"holds": "orders",
|
||||||
"reservations": "reservations"
|
"reservations": "reservations"
|
||||||
},
|
},
|
||||||
"checked_out": {
|
"checked_out": {
|
||||||
|
|||||||
Reference in New Issue
Block a user