diff --git a/src/app/_helpers/service-handler.interceptor.ts b/src/app/_helpers/service-handler.interceptor.ts
index 9befe749..8b98afae 100644
--- a/src/app/_helpers/service-handler.interceptor.ts
+++ b/src/app/_helpers/service-handler.interceptor.ts
@@ -29,7 +29,7 @@ export class ServiceHandlerInterceptor implements HttpInterceptor {
this.logger.error(errorMessage);
- return throwError(errorMessage);
+ return throwError(error);
}),
);
}
diff --git a/src/app/modules/data/data.module.ts b/src/app/modules/data/data.module.ts
index 2e2dacbf..b83c4ba5 100644
--- a/src/app/modules/data/data.module.ts
+++ b/src/app/modules/data/data.module.ts
@@ -90,6 +90,7 @@ import {TreeListComponent} from './list/tree-list.component';
import {TreeListFragmentComponent} from './list/tree-list-fragment.component';
import {SettingsProvider} from '../settings/settings.provider';
import {IonIconModule} from '../../util/ion-icon/ion-icon.module';
+import {ExternalLinkComponent} from './elements/external-link.component';
/**
* Module for handling data
@@ -150,6 +151,7 @@ import {IonIconModule} from '../../util/ion-icon/ion-icon.module';
VideoListItemComponent,
SimpleDataListComponent,
TitleCardComponent,
+ ExternalLinkComponent,
],
entryComponents: [DataListComponent, SimpleDataListComponent],
imports: [
@@ -201,6 +203,7 @@ import {IonIconModule} from '../../util/ion-icon/ion-icon.module';
OriginDetailComponent,
FavoriteButtonComponent,
TreeListComponent,
+ ExternalLinkComponent,
],
})
export class DataModule {}
diff --git a/src/app/modules/data/elements/external-link.component.ts b/src/app/modules/data/elements/external-link.component.ts
new file mode 100644
index 00000000..108d8205
--- /dev/null
+++ b/src/app/modules/data/elements/external-link.component.ts
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2022 StApps
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation, version 3.
+ *
+ * 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 General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see .
+ */
+
+import {Component, Input} from '@angular/core';
+import {Browser} from '../../../util/browser.factory';
+
+@Component({
+ selector: 'stapps-external-link',
+ templateUrl: './external-link.html',
+ styleUrls: ['./external-link.scss'],
+})
+export class ExternalLinkComponent {
+ @Input() link: string;
+
+ @Input() text: string;
+
+ constructor(private browser: Browser) {}
+
+ onLinkClick(url: string) {
+ this.browser.open(url);
+ }
+}
diff --git a/src/app/modules/data/elements/external-link.html b/src/app/modules/data/elements/external-link.html
new file mode 100644
index 00000000..605bfc3a
--- /dev/null
+++ b/src/app/modules/data/elements/external-link.html
@@ -0,0 +1,17 @@
+
+{{ text }}
+
diff --git a/src/app/modules/data/elements/external-link.scss b/src/app/modules/data/elements/external-link.scss
new file mode 100644
index 00000000..b2f61708
--- /dev/null
+++ b/src/app/modules/data/elements/external-link.scss
@@ -0,0 +1,8 @@
+:host a {
+ cursor: pointer;
+ ion-icon {
+ vertical-align: text-top;
+ font-size: 80%;
+ padding-left: 2px;
+ }
+}
diff --git a/src/app/modules/data/types/message/message-detail-content.html b/src/app/modules/data/types/message/message-detail-content.html
index 2f9f950f..35803a40 100644
--- a/src/app/modules/data/types/message/message-detail-content.html
+++ b/src/app/modules/data/types/message/message-detail-content.html
@@ -1,16 +1,16 @@
@@ -59,9 +59,10 @@
{{ 'sameAs' | propertyNameTranslate: item | titlecase }}
- {{ item.name }}
-
+
diff --git a/src/app/modules/data/types/message/message-detail-content.scss b/src/app/modules/data/types/message/message-detail-content.scss
index 13622255..4a4473bb 100644
--- a/src/app/modules/data/types/message/message-detail-content.scss
+++ b/src/app/modules/data/types/message/message-detail-content.scss
@@ -21,14 +21,6 @@
display: block;
}
}
- a {
- cursor: pointer;
- ion-icon {
- vertical-align: text-top;
- font-size: 80%;
- padding-left: 2px;
- }
- }
// Show smaller image on a desktop
@media (min-width: 992px) {
ion-thumbnail {
diff --git a/src/app/modules/hebis/daia-availability/daia-availability.component.ts b/src/app/modules/hebis/daia-availability/daia-availability.component.ts
index 551333e1..d78e1c8a 100644
--- a/src/app/modules/hebis/daia-availability/daia-availability.component.ts
+++ b/src/app/modules/hebis/daia-availability/daia-availability.component.ts
@@ -20,7 +20,7 @@ import {FavoritesService} from '../../favorites/favorites.service';
import {DataProvider} from '../../data/data.provider';
import {DataDetailComponent} from '../../data/detail/data-detail.component';
import {DaiaDataProvider} from '../daia-data.provider';
-import {SCDaiaHoldings} from '../protocol/response';
+import {SCDaiaHolding} from '../protocol/response';
import {ModalController} from '@ionic/angular';
/**
@@ -35,7 +35,7 @@ export class DaiaAvailabilityComponent
extends DataDetailComponent
implements OnInit
{
- holdings: SCDaiaHoldings[] | undefined;
+ holdings: SCDaiaHolding[] | undefined;
/**
*
diff --git a/src/app/modules/hebis/daia-availability/daia-availability.html b/src/app/modules/hebis/daia-availability/daia-availability.html
index fdda0882..97c9b4f4 100644
--- a/src/app/modules/hebis/daia-availability/daia-availability.html
+++ b/src/app/modules/hebis/daia-availability/daia-availability.html
@@ -4,60 +4,7 @@
-
-
- {{ holding.label }}
-
-
-
-
- {{
- 'hebisSearch.daia.signature' | translate
- }}
- {{ holding.signature }}
-
- {{
- 'hebisSearch.daia.ejournal' | translate
- }}
-
-
-
- {{
- 'hebisSearch.daia.location' | translate
- }}
-
-
-
- {{
- 'hebisSearch.daia.comment' | translate
- }}
-
-
-
- {{
- 'hebisSearch.daia.status' | translate
- }}
- {{ 'hebisSearch.daia.available' | translate }}
- {{ 'hebisSearch.daia.order' | translate }}
-
-
+
{{ 'hebisSearch.daia.unavailableAvailability' | translate }}
diff --git a/src/app/modules/hebis/daia-availability/daia-availability.scss b/src/app/modules/hebis/daia-availability/daia-availability.scss
index 2b8cc024..636eece5 100644
--- a/src/app/modules/hebis/daia-availability/daia-availability.scss
+++ b/src/app/modules/hebis/daia-availability/daia-availability.scss
@@ -1,4 +1,19 @@
-ion-card {
+/*!
+ * Copyright (C) 2022 StApps
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation, version 3.
+ *
+ * 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 General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see .
+ */
+
+:host ion-card {
margin: 0;
box-shadow: none;
ion-card-content {
@@ -13,26 +28,4 @@ ion-card {
padding-bottom: 4px;
font-weight: bold;
}
- ion-card-content {
- ion-label a {
- display: block;
- text-decoration: none;
- font-weight: 700;
- color: var(--ion-color-primary);
- margin: 20px 0 5px;
- }
- ion-grid {
- padding: 0;
-
- ion-row {
- background-color: var(--ion-color-light);
- color: var(--ion-color-light-contrast);
- border-bottom: 1px solid #fff;
-
- ion-col:first-child {
- font-weight: 700;
- }
- }
- }
- }
}
diff --git a/src/app/modules/hebis/daia-availability/daia-holding.component.ts b/src/app/modules/hebis/daia-availability/daia-holding.component.ts
new file mode 100644
index 00000000..57f1fa04
--- /dev/null
+++ b/src/app/modules/hebis/daia-availability/daia-holding.component.ts
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2022 StApps
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation, version 3.
+ *
+ * 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 General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see .
+ */
+
+import {Component, Input, OnInit} from '@angular/core';
+import {SCDaiaHolding} from '../protocol/response';
+import {DaiaDataProvider} from '../daia-data.provider';
+
+@Component({
+ selector: 'stapps-daia-holding',
+ templateUrl: './daia-holding.html',
+ styleUrls: ['./daia-holding.scss'],
+})
+export class DaiaHoldingComponent implements OnInit {
+ @Input() holding: SCDaiaHolding;
+
+ constructor(private daiaDataProvider: DaiaDataProvider) {}
+
+ resourceLink?: string;
+
+ ngOnInit(): void {
+ console.log(this.holding);
+ this.resourceLink = this.daiaDataProvider.getHoldingLink(this.holding);
+ }
+}
diff --git a/src/app/modules/hebis/daia-availability/daia-holding.html b/src/app/modules/hebis/daia-availability/daia-holding.html
new file mode 100644
index 00000000..b37bab12
--- /dev/null
+++ b/src/app/modules/hebis/daia-availability/daia-holding.html
@@ -0,0 +1,89 @@
+
+
+
+
+
+
+
+
+ {{ 'hebisSearch.daia.location' | translate }}
+
+
+
+ {{ 'hebisSearch.daia.signature' | translate }}
+ {{ holding.signature }}
+
+
+ {{ 'hebisSearch.daia.comment' | translate }}
+
+
+
+ {{ 'Online' }}
+
+
+
+
+
+ {{ 'hebisSearch.daia.status' | translate }}
+
+
+
+ -1
+ "
+ name="cancel"
+ color="danger"
+ >
+
+ {{ 'hebisSearch.daia.status_states' + '.' + holding.status | translate }}
+
+
+
+
+
+
+
+ {{ 'hebisSearch.daia.dueDate' | translate }}
+ {{ holding.dueDate | amDateFormat: 'll' }}
+
+
diff --git a/src/app/modules/hebis/daia-availability/daia-holding.scss b/src/app/modules/hebis/daia-availability/daia-holding.scss
new file mode 100644
index 00000000..078fae64
--- /dev/null
+++ b/src/app/modules/hebis/daia-availability/daia-holding.scss
@@ -0,0 +1,38 @@
+/*!
+ * Copyright (C) 2022 StApps
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation, version 3.
+ *
+ * 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 General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see .
+ */
+ion-label a {
+ display: block;
+ text-decoration: none;
+ font-weight: 700;
+ color: var(--ion-color-primary);
+ margin: 20px 0 5px;
+}
+ion-grid {
+ padding: 0;
+
+ ion-row {
+ background-color: var(--ion-color-light);
+ color: var(--ion-color-light-contrast);
+ border-bottom: 1px solid #fff;
+
+ ion-col:first-child {
+ font-weight: 700;
+ }
+ }
+}
+
+ion-icon ::ng-deep stapps-icon {
+ --fill: 1;
+}
diff --git a/src/app/modules/hebis/daia-data.provider.spec.ts b/src/app/modules/hebis/daia-data.provider.spec.ts
new file mode 100644
index 00000000..7f151b8c
--- /dev/null
+++ b/src/app/modules/hebis/daia-data.provider.spec.ts
@@ -0,0 +1,235 @@
+/*
+ * Copyright (C) 2022 StApps
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation, version 3.
+ *
+ * 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 General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see .
+ */
+/* eslint-disable @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-explicit-any, unicorn/no-thenable */
+import {TestBed} from '@angular/core/testing';
+import {DaiaDataProvider} from './daia-data.provider';
+import {HebisModule} from './hebis.module';
+import {ConfigProvider} from '../config/config.provider';
+import {StAppsWebHttpClient} from '../data/stapps-web-http-client.provider';
+import {StorageProvider} from '../storage/storage.provider';
+import {LoggerConfig, LoggerModule, NGXLogger} from 'ngx-logger';
+import {MapModule} from '../map/map.module';
+import {HttpClientModule} from '@angular/common/http';
+import {StorageModule} from '../storage/storage.module';
+import {SCDaiaHolding, SCDaiaService} from './protocol/response';
+import {Observable, of} from 'rxjs';
+import {TranslateLoader, TranslateModule} from '@ngx-translate/core';
+
+const translations: any = {data: {detail: {TITLE: 'Foo'}}};
+
+class TranslateFakeLoader implements TranslateLoader {
+ getTranslation(_lang: string): Observable {
+ return of(translations);
+ }
+}
+
+describe('DaiaDataProvider', () => {
+ let daiaDataProvider: DaiaDataProvider;
+ let configProvider: ConfigProvider;
+ const proxyUrl = 'https://some-proxy.com?q=';
+ beforeEach(async () => {
+ configProvider = jasmine.createSpyObj('ConfigProvider', ['getValue']);
+ TestBed.configureTestingModule({
+ imports: [
+ HebisModule,
+ MapModule,
+ HttpClientModule,
+ StorageModule,
+ LoggerModule,
+ TranslateModule.forRoot({
+ loader: {provide: TranslateLoader, useClass: TranslateFakeLoader},
+ }),
+ ],
+ providers: [
+ {
+ provide: ConfigProvider,
+ useValue: configProvider,
+ },
+ StAppsWebHttpClient,
+ StorageProvider,
+ NGXLogger,
+ LoggerConfig,
+ DaiaDataProvider,
+ ],
+ });
+ daiaDataProvider = TestBed.inject(DaiaDataProvider);
+ daiaDataProvider.hebisProxyUrl = proxyUrl;
+ });
+ describe('getResourceLink', () => {
+ it('should return undefined when available not defined', () => {
+ const holding: SCDaiaHolding = {
+ id: '',
+ label: '',
+ online: false,
+ signature: '',
+ };
+
+ expect(daiaDataProvider.getHoldingLink(holding)).toEqual(undefined);
+ });
+
+ it('should return the resource link without proxy when service is openaccess', () => {
+ const available: SCDaiaService = {
+ delay: '',
+ expected: '',
+ href: 'https://some-url.com',
+ limitations: [],
+ service: 'openaccess',
+ };
+ const holding: SCDaiaHolding = {
+ id: '',
+ label: '',
+ online: false,
+ signature: '',
+ available: available,
+ };
+
+ expect(daiaDataProvider.getHoldingLink(holding)).toEqual(available.href);
+ });
+
+ it('should return the resource link with proxy when service is not openaccess', () => {
+ const available: SCDaiaService = {
+ delay: '',
+ expected: '',
+ href: 'https://some-url.com',
+ limitations: [],
+ service: 'other',
+ };
+ const holding: SCDaiaHolding = {
+ id: '',
+ label: '',
+ online: false,
+ signature: '',
+ available: available,
+ };
+
+ expect(daiaDataProvider.getHoldingLink(holding)).toEqual(
+ `${proxyUrl}${available.href}`,
+ );
+ });
+ });
+
+ describe('getResourceStatus', () => {
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
+ // let available, unavalable: SCDaiaService[];
+
+ const checkedOut: SCDaiaService = {
+ expected: '2022-09-01',
+ limitations: [],
+ service: 'loan',
+ };
+
+ const notYetAvailableOnBuy: SCDaiaService = {
+ limitations: [{id: 'OnBuy', content: ''}],
+ service: 'loan',
+ };
+
+ const notYetAvailableJustReturned: SCDaiaService = {
+ limitations: [{id: 'JustReturned', content: ''}],
+ service: 'loan',
+ };
+
+ const notAvailableCopyIsMissing: SCDaiaService = {
+ limitations: [{id: 'CopyIsMissing', content: ''}],
+ service: 'loan',
+ };
+
+ const notAvailableCanceled: SCDaiaService = {
+ limitations: [{id: 'Canceled', content: ''}],
+ service: 'loan',
+ };
+
+ const libraryOnlyOnlyInHouse: SCDaiaService = {
+ limitations: [{id: 'OnlyInHouse', content: ''}],
+ service: 'loan',
+ };
+
+ const libraryOnlyExternalLoan: SCDaiaService = {
+ limitations: [{id: 'ExternalLoan', content: ''}],
+ service: 'loan',
+ };
+
+ const libraryOnlyNoLimitations: SCDaiaService = {
+ service: 'loan',
+ };
+
+ const availableLimitationsUndefined: SCDaiaService = {
+ service: 'loan',
+ };
+
+ const availableLimitationsEmpty: SCDaiaService = {
+ limitations: [],
+ service: 'loan',
+ };
+
+ it('should return check out', () => {
+ expect(daiaDataProvider.getHoldingStatus([], [checkedOut])).toEqual(
+ 'checked_out',
+ );
+ });
+
+ it('should return not yet available', () => {
+ expect(
+ daiaDataProvider.getHoldingStatus([], [notYetAvailableOnBuy]),
+ ).toEqual('not_yet_available');
+ expect(
+ daiaDataProvider.getHoldingStatus([], [notYetAvailableJustReturned]),
+ ).toEqual('not_yet_available');
+ });
+
+ it('should return not available', () => {
+ expect(
+ daiaDataProvider.getHoldingStatus([], [notAvailableCopyIsMissing]),
+ ).toEqual('not_available');
+ expect(
+ daiaDataProvider.getHoldingStatus([], [notAvailableCanceled]),
+ ).toEqual('not_available');
+ });
+
+ it('should return library only', () => {
+ expect(
+ daiaDataProvider.getHoldingStatus([], [libraryOnlyOnlyInHouse]),
+ ).toEqual('library_only');
+ expect(
+ daiaDataProvider.getHoldingStatus([libraryOnlyExternalLoan], []),
+ ).toEqual('library_only');
+ expect(
+ daiaDataProvider.getHoldingStatus([], [libraryOnlyNoLimitations]),
+ ).toEqual('library_only');
+ });
+
+ it('should return available', () => {
+ expect(
+ daiaDataProvider.getHoldingStatus([availableLimitationsUndefined], []),
+ ).toEqual('available');
+ expect(
+ daiaDataProvider.getHoldingStatus([availableLimitationsEmpty], []),
+ ).toEqual('available');
+ });
+
+ it('should return unknown otherwise', () => {
+ const withoutLoan: SCDaiaService = {
+ limitations: [],
+ service: 'anything else',
+ };
+
+ expect(daiaDataProvider.getHoldingStatus([withoutLoan], [])).toEqual(
+ 'unknown',
+ );
+ expect(daiaDataProvider.getHoldingStatus([], [withoutLoan])).toEqual(
+ 'unknown',
+ );
+ });
+ });
+});
diff --git a/src/app/modules/hebis/daia-data.provider.ts b/src/app/modules/hebis/daia-data.provider.ts
index d9220cb0..a7defdc9 100644
--- a/src/app/modules/hebis/daia-data.provider.ts
+++ b/src/app/modules/hebis/daia-data.provider.ts
@@ -13,12 +13,18 @@
* this program. If not, see .
*/
import {Injectable} from '@angular/core';
-import {SCDaiaAvailabilityResponse, SCDaiaHoldings} from './protocol/response';
+import {
+ SCDaiaAvailabilityResponse,
+ SCDaiaHolding,
+ SCDaiaService,
+ SCDaiaSimpleContent,
+} from './protocol/response';
import {StorageProvider} from '../storage/storage.provider';
import {HttpClient, HttpHeaders} from '@angular/common/http';
import {ConfigProvider} from '../config/config.provider';
import {SCFeatureConfiguration} from '@openstapps/core';
import {NGXLogger} from 'ngx-logger';
+import {TranslateService} from '@ngx-translate/core';
/**
* Generated class for the DataProvider provider.
@@ -37,9 +43,9 @@ export class DaiaDataProvider {
httpClient: HttpClient;
- configProvider: ConfigProvider;
+ daiaServiceUrl?: string;
- daiaServiceUrl: string | undefined;
+ hebisProxyUrl?: string;
clientHeaders = new HttpHeaders();
@@ -50,23 +56,24 @@ export class DaiaDataProvider {
* @param httpClient TODO
* @param configProvider TODO
* @param logger TODO
+ * @param translateService TODO
*/
constructor(
storageProvider: StorageProvider,
httpClient: HttpClient,
- configProvider: ConfigProvider,
+ private configProvider: ConfigProvider,
private readonly logger: NGXLogger,
+ private translateService: TranslateService,
) {
this.storageProvider = storageProvider;
this.httpClient = httpClient;
- this.configProvider = configProvider;
this.clientHeaders = this.clientHeaders.set(
'Content-Type',
'application/json',
);
}
- async getAvailability(id: string): Promise {
+ async getAvailability(id: string): Promise {
if (typeof this.daiaServiceUrl === 'undefined') {
try {
const features = this.configProvider.getValue(
@@ -78,6 +85,12 @@ export class DaiaDataProvider {
this.logger.error('Daia service url undefined');
return undefined;
}
+ if (features.extern?.hebisProxy?.url) {
+ this.hebisProxyUrl = features.extern?.hebisProxy?.url;
+ } else {
+ this.logger.error('HeBIS proxy url undefined');
+ return undefined;
+ }
} catch (error) {
this.logger.error(error);
return undefined;
@@ -86,11 +99,12 @@ export class DaiaDataProvider {
return new Promise(resolve =>
this.httpClient
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- .get(this.daiaServiceUrl!, {params: {id}})
+ .get(this.daiaServiceUrl as string, {
+ params: {id, lang: this.translateService.currentLang},
+ })
.subscribe(
(response: SCDaiaAvailabilityResponse) => {
- const holdings: SCDaiaHoldings[] = [];
+ const holdings: SCDaiaHolding[] = [];
if (response && Array.isArray(response.document)) {
response.document.map(document => {
Array.isArray(document.item) &&
@@ -106,17 +120,43 @@ export class DaiaDataProvider {
about,
available,
storage,
+ unavailable,
} = element;
const holdingIndex = holdings.findIndex(
holding => holding.id === departmentId,
);
if (holdingIndex === -1) {
+ const holdingStatus = this.holdingHasStatus(
+ available || [],
+ )
+ ? this.getHoldingStatus(
+ available || [],
+ unavailable || [],
+ )
+ : undefined;
+
+ const dueDate =
+ holdingStatus === 'checked_out'
+ ? (
+ unavailable.find(
+ item => item.service === 'loan',
+ ) as SCDaiaService
+ ).expected
+ : undefined;
+
holdings.push({
id: departmentId,
label: departmentLabel,
href: departmentLink,
signature: label,
+ status: holdingStatus,
+ dueDate: dueDate,
+ online:
+ Array.isArray(available) &&
+ typeof available.find(
+ item => item.service === 'remote',
+ ) !== 'undefined',
available:
(Array.isArray(available) &&
(available.find(
@@ -126,6 +166,12 @@ export class DaiaDataProvider {
item => item.service === 'loan',
))) ||
undefined,
+ unavailable:
+ (Array.isArray(unavailable) &&
+ unavailable.find(
+ item => item.service === 'loan',
+ )) ||
+ undefined,
storage,
about,
});
@@ -139,11 +185,85 @@ export class DaiaDataProvider {
resolve(holdings);
},
error => {
- this.logger.error(error);
+ // handle "availability info not found" separately from the problems with getting the info
+ if (error.status === 404) resolve([]);
// eslint-disable-next-line unicorn/no-useless-undefined
resolve(undefined);
},
),
);
}
+
+ getHoldingLink(holding: SCDaiaHolding) {
+ if (typeof this.hebisProxyUrl === 'undefined') {
+ this.logger.error('HeBIS proxy url undefined');
+
+ return;
+ }
+ const resourceLink = holding.available?.href;
+
+ if (
+ typeof resourceLink === 'undefined' ||
+ holding.available?.service === 'openaccess'
+ ) {
+ return resourceLink;
+ }
+
+ return `${this.hebisProxyUrl}${resourceLink}`;
+ }
+
+ holdingHasStatus(available: SCDaiaService[]): boolean {
+ return !available.some(item => item.service === 'remote');
+ }
+
+ getHoldingStatus(
+ available: SCDaiaService[],
+ unavailable: SCDaiaService[],
+ ): SCDaiaHolding['status'] {
+ const loan: {available: number; unavailable: number} = {
+ available: available.findIndex(item => item.service === 'loan'),
+ unavailable: unavailable.findIndex(item => item.service === 'loan'),
+ };
+ if (
+ loan.unavailable !== -1 &&
+ typeof unavailable[loan.unavailable].expected !== 'undefined'
+ ) {
+ return 'checked_out';
+ }
+
+ if (
+ loan.unavailable !== -1 &&
+ unavailable[loan.unavailable].limitations?.some(limitation =>
+ ['OnBuy', 'JustReturned'].includes(limitation.id),
+ )
+ )
+ return 'not_yet_available';
+
+ if (
+ loan.unavailable !== -1 &&
+ unavailable[loan.unavailable].limitations?.some(limitation =>
+ ['CopyIsMissing', 'Canceled'].includes(limitation.id),
+ )
+ )
+ return 'not_available';
+
+ if (
+ (loan.unavailable !== -1 &&
+ (!Array.isArray(unavailable[loan.unavailable].limitations) ||
+ (unavailable[loan.unavailable].limitations as SCDaiaSimpleContent[])
+ .length === 0 ||
+ unavailable[loan.unavailable].limitations?.some(limitation =>
+ ['OnlyInHouse'].includes(limitation.id),
+ ))) ||
+ (loan.available !== -1 &&
+ available[loan.available].limitations?.some(limitation =>
+ ['ExternalLoan'].includes(limitation.id),
+ ))
+ )
+ return 'library_only';
+
+ if (loan.available !== -1) return 'available';
+
+ return 'unknown';
+ }
}
diff --git a/src/app/modules/hebis/hebis-detail/hebis-detail.component.ts b/src/app/modules/hebis/hebis-detail/hebis-detail.component.ts
index c0c89756..0d88b16f 100644
--- a/src/app/modules/hebis/hebis-detail/hebis-detail.component.ts
+++ b/src/app/modules/hebis/hebis-detail/hebis-detail.component.ts
@@ -20,7 +20,7 @@ import {HebisDataProvider} from '../hebis-data.provider';
import {FavoritesService} from '../../favorites/favorites.service';
import {DataProvider} from '../../data/data.provider';
import {DataDetailComponent} from '../../data/detail/data-detail.component';
-import {SCDaiaHoldings} from '../protocol/response';
+import {SCDaiaHolding} from '../protocol/response';
import {ModalController} from '@ionic/angular';
/**
@@ -32,7 +32,7 @@ import {ModalController} from '@ionic/angular';
templateUrl: 'hebis-detail.html',
})
export class HebisDetailComponent extends DataDetailComponent {
- holdings: SCDaiaHoldings[];
+ holdings: SCDaiaHolding[];
/**
*
diff --git a/src/app/modules/hebis/hebis.module.ts b/src/app/modules/hebis/hebis.module.ts
index bc70867f..7004ee57 100644
--- a/src/app/modules/hebis/hebis.module.ts
+++ b/src/app/modules/hebis/hebis.module.ts
@@ -1,16 +1,16 @@
/*
- * Copyright (C) 2022 StApps
- * This program is free software: you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation, version 3.
+ * Copyright (C) 2018-2022 StApps
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation, version 3.
*
- * 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 General Public License for
- * more details.
+ * 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 General Public License for
+ * more details.
*
- * You should have received a copy of the GNU General Public License along with
- * this program. If not, see .
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see .
*/
import {ScrollingModule} from '@angular/cdk/scrolling';
import {CommonModule} from '@angular/common';
@@ -44,6 +44,7 @@ import {DataListComponent} from '../data/list/data-list.component';
import {DaiaAvailabilityComponent} from './daia-availability/daia-availability.component';
import {UtilModule} from '../../util/util.module';
import {IonIconModule} from '../../util/ion-icon/ion-icon.module';
+import {DaiaHoldingComponent} from './daia-availability/daia-holding.component';
/**
* Module for handling data
@@ -60,6 +61,7 @@ import {IonIconModule} from '../../util/ion-icon/ion-icon.module';
PeriodicalListItemComponent,
HebisArticleListItemComponent,
HebisArticleContentComponent,
+ DaiaHoldingComponent,
],
entryComponents: [DataListComponent],
imports: [
diff --git a/src/app/modules/hebis/protocol/response.ts b/src/app/modules/hebis/protocol/response.ts
index f7bbff91..65f6fc9b 100644
--- a/src/app/modules/hebis/protocol/response.ts
+++ b/src/app/modules/hebis/protocol/response.ts
@@ -44,15 +44,26 @@ export interface SCDaiaService {
delay?: string;
href?: string;
service: string;
+ expected?: string;
limitations?: SCDaiaSimpleContent[];
}
-export interface SCDaiaHoldings {
+export interface SCDaiaHolding {
id: string;
label: string;
href?: string;
signature: string;
storage?: SCDaiaSimpleContent;
available?: SCDaiaService;
+ unavailable?: SCDaiaService;
about?: string;
+ online: boolean;
+ dueDate?: string;
+ status?:
+ | 'checked_out'
+ | 'not_yet_available'
+ | 'not_available'
+ | 'library_only'
+ | 'available'
+ | 'unknown';
}
diff --git a/src/app/modules/hebis/types/book/book-detail-content.html b/src/app/modules/hebis/types/book/book-detail-content.html
index 4782d948..a49b97fa 100644
--- a/src/app/modules/hebis/types/book/book-detail-content.html
+++ b/src/app/modules/hebis/types/book/book-detail-content.html
@@ -18,9 +18,10 @@
'hebisSearch.detail.title' | translate | sentencecase
}}
- {{
- 'name' | thingTranslate: item
- }}
+
diff --git a/src/app/modules/hebis/types/hebis-article/hebis-article-content.html b/src/app/modules/hebis/types/hebis-article/hebis-article-content.html
index 782a5b51..0b82bac8 100644
--- a/src/app/modules/hebis/types/hebis-article/hebis-article-content.html
+++ b/src/app/modules/hebis/types/hebis-article/hebis-article-content.html
@@ -18,9 +18,10 @@
'hebisSearch.detail.title' | translate | sentencecase
}}
- {{
- 'name' | thingTranslate: item
- }}
+
diff --git a/src/app/modules/hebis/types/periodical/periodical-detail-content.html b/src/app/modules/hebis/types/periodical/periodical-detail-content.html
index 68e5814e..a4c2f5e8 100644
--- a/src/app/modules/hebis/types/periodical/periodical-detail-content.html
+++ b/src/app/modules/hebis/types/periodical/periodical-detail-content.html
@@ -18,9 +18,10 @@
'hebisSearch.detail.title' | translate | sentencecase
}}
- {{
- 'name' | thingTranslate: item
- }}
+
diff --git a/src/app/modules/news/item/news-item.component.ts b/src/app/modules/news/item/news-item.component.ts
index 315db6b6..4c5634bd 100644
--- a/src/app/modules/news/item/news-item.component.ts
+++ b/src/app/modules/news/item/news-item.component.ts
@@ -14,7 +14,7 @@
*/
import {Component, Input} from '@angular/core';
import {SCMessage} from '@openstapps/core';
-import {Browser} from '../../../util/browser.factory';
+
/**
* News page component
*/
@@ -24,14 +24,8 @@ import {Browser} from '../../../util/browser.factory';
styleUrls: ['news-item.scss'],
})
export class NewsItemComponent {
- constructor(private browser: Browser) {}
-
/**
* News (message) to show
*/
@Input() item: SCMessage;
-
- onLinkClick(url: string) {
- this.browser.open(url);
- }
}
diff --git a/src/assets/i18n/de.json b/src/assets/i18n/de.json
index 0caf5c89..4e7cbb5b 100644
--- a/src/assets/i18n/de.json
+++ b/src/assets/i18n/de.json
@@ -349,16 +349,26 @@
},
"daia": {
"availability": "Verfügbarkeit",
- "available": "ausleihbar",
"status": "Status",
+ "status_states": {
+ "checked_out": "ausgeliehen",
+ "not_yet_available": "noch nicht verfügbar",
+ "not_available": "nicht verfügbar",
+ "library_only": "nur vor Ort benutzbar",
+ "available": "ausleihbar",
+ "unknown": "unbekannt"
+ },
+ "dueDate": "Leihfristende",
"location": "Standort",
"signature": "Signatur",
"comment": "Kommentar",
- "order": "Bestellen",
+ "order": "bestellen",
+ "reserve": "vormerken",
"issn": "ISSN",
"ejournal": "ejournal",
"unknownAvailability": "Keine Information vorhanden",
- "unavailableAvailability": "System nicht erreichbar"
+ "unavailableAvailability": "System nicht erreichbar",
+ "fulltext": "Zum Volltext"
}
},
"schedule": {
diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json
index bfb94c1a..7b18c2ab 100644
--- a/src/assets/i18n/en.json
+++ b/src/assets/i18n/en.json
@@ -349,16 +349,26 @@
},
"daia": {
"availability": "Availability",
- "available": "available",
"status": "Status",
+ "status_states": {
+ "checked_out": "checked out",
+ "not_yet_available": "not yet available",
+ "not_available": "not available",
+ "library_only": "for use in library only",
+ "available": "available",
+ "unknown": "not available"
+ },
+ "dueDate": "Due date",
"location": "Location",
"signature": "Shelfmark",
"comment": "Remark",
- "order": "Request",
+ "order": "request",
+ "reserve": "reserve",
"issn": "ISSN",
"ejournal": "ejournal",
"unknownAvailability": "No information available",
- "unavailableAvailability": "System unreachable"
+ "unavailableAvailability": "System unreachable",
+ "fulltext": "Full text"
}
},
"schedule": {
diff --git a/src/global.scss b/src/global.scss
index a37890a9..76622cb4 100644
--- a/src/global.scss
+++ b/src/global.scss
@@ -114,6 +114,13 @@ ion-card.bold-header {
font-weight: bold;
}
}
+ion-header {
+ stapps-favorite-button {
+ ion-icon {
+ color: var(--ion-color-light);
+ }
+ }
+}
.ion-content-parallax {
@include ion-content-parallax()