feat: display availability and item data for library items

This commit is contained in:
Jovan Krunić
2022-09-08 13:02:19 +00:00
committed by Thea Schöbl
parent 605aa1b782
commit d571b1dbe5
25 changed files with 695 additions and 145 deletions

View File

@@ -13,12 +13,18 @@
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
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<SCDaiaHoldings[] | undefined> {
async getAvailability(id: string): Promise<SCDaiaHolding[] | undefined> {
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<SCDaiaAvailabilityResponse>(this.daiaServiceUrl!, {params: {id}})
.get<SCDaiaAvailabilityResponse>(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';
}
}