mirror of
https://gitlab.com/openstapps/openstapps.git
synced 2026-03-14 18:52:33 +00:00
feat: add HeBIS HDS search
This commit is contained in:
committed by
Jovan Krunić
parent
e4165901bb
commit
9a3241c42a
112
package-lock.json
generated
112
package-lock.json
generated
@@ -2282,6 +2282,16 @@
|
|||||||
"serve-index": "^1.9.1"
|
"serve-index": "^1.9.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"cors": {
|
||||||
|
"version": "2.8.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
|
||||||
|
"integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"object-assign": "^4",
|
||||||
|
"vary": "^1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"debug": {
|
"debug": {
|
||||||
"version": "2.6.9",
|
"version": "2.6.9",
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||||
@@ -2328,6 +2338,12 @@
|
|||||||
"is-wsl": "^2.2.0"
|
"is-wsl": "^2.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"proxy-middleware": {
|
||||||
|
"version": "0.15.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/proxy-middleware/-/proxy-middleware-0.15.0.tgz",
|
||||||
|
"integrity": "sha1-o/3xvvtzD5UZZYcqwvYHTGFHelY=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"send": {
|
"send": {
|
||||||
"version": "0.17.2",
|
"version": "0.17.2",
|
||||||
"resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz",
|
"resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz",
|
||||||
@@ -2576,6 +2592,13 @@
|
|||||||
"integrity": "sha512-lOrkktadlKYbYf1LrDyAtsu1JnQ0oCCdkOU7iHQ8oXnNOkMwobFfD2m62F1CoOr0u9LIkpYnZSPjng8lZbmbNw==",
|
"integrity": "sha512-lOrkktadlKYbYf1LrDyAtsu1JnQ0oCCdkOU7iHQ8oXnNOkMwobFfD2m62F1CoOr0u9LIkpYnZSPjng8lZbmbNw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/cordova": "^0.0.34"
|
"@types/cordova": "^0.0.34"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@types/cordova": {
|
||||||
|
"version": "0.0.34",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/cordova/-/cordova-0.0.34.tgz",
|
||||||
|
"integrity": "sha1-6nrd907Ow9dimCegw54smt3HPQQ="
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@ionic-native/diagnostic": {
|
"@ionic-native/diagnostic": {
|
||||||
@@ -2584,6 +2607,13 @@
|
|||||||
"integrity": "sha512-ovzydKPNNK3zu1A0e9Z+cc8oSKaVmuV6DxCE82+KSyPddZzHuzZq/56us39WjlqQ07KDDKLwlGmIib9VGB1Y/A==",
|
"integrity": "sha512-ovzydKPNNK3zu1A0e9Z+cc8oSKaVmuV6DxCE82+KSyPddZzHuzZq/56us39WjlqQ07KDDKLwlGmIib9VGB1Y/A==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/cordova": "^0.0.34"
|
"@types/cordova": "^0.0.34"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@types/cordova": {
|
||||||
|
"version": "0.0.34",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/cordova/-/cordova-0.0.34.tgz",
|
||||||
|
"integrity": "sha1-6nrd907Ow9dimCegw54smt3HPQQ="
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@ionic-native/dialogs": {
|
"@ionic-native/dialogs": {
|
||||||
@@ -2592,6 +2622,13 @@
|
|||||||
"integrity": "sha512-cCvwbD/duIL1CVVpgSwwgvyGYuUzL83jFAjPye7WX0ZzqZrh5ifvLjCAw0B+7YFv7Hd3FXZn+04cqvYcZLFcEQ==",
|
"integrity": "sha512-cCvwbD/duIL1CVVpgSwwgvyGYuUzL83jFAjPye7WX0ZzqZrh5ifvLjCAw0B+7YFv7Hd3FXZn+04cqvYcZLFcEQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/cordova": "^0.0.34"
|
"@types/cordova": "^0.0.34"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@types/cordova": {
|
||||||
|
"version": "0.0.34",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/cordova/-/cordova-0.0.34.tgz",
|
||||||
|
"integrity": "sha1-6nrd907Ow9dimCegw54smt3HPQQ="
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@ionic-native/geolocation": {
|
"@ionic-native/geolocation": {
|
||||||
@@ -2600,6 +2637,13 @@
|
|||||||
"integrity": "sha512-Fk7YXBn9/dOBGqtySSQgoCg7OLlmS8M6Y1Xa3hjgZBzFU0NPb9nnhVuMWI5Wp2qH/7cuzWRB7kEp4oN2tZ6fbw==",
|
"integrity": "sha512-Fk7YXBn9/dOBGqtySSQgoCg7OLlmS8M6Y1Xa3hjgZBzFU0NPb9nnhVuMWI5Wp2qH/7cuzWRB7kEp4oN2tZ6fbw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/cordova": "^0.0.34"
|
"@types/cordova": "^0.0.34"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@types/cordova": {
|
||||||
|
"version": "0.0.34",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/cordova/-/cordova-0.0.34.tgz",
|
||||||
|
"integrity": "sha1-6nrd907Ow9dimCegw54smt3HPQQ="
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@ionic-native/http": {
|
"@ionic-native/http": {
|
||||||
@@ -2609,6 +2653,14 @@
|
|||||||
"optional": true,
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/cordova": "^0.0.34"
|
"@types/cordova": "^0.0.34"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@types/cordova": {
|
||||||
|
"version": "0.0.34",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/cordova/-/cordova-0.0.34.tgz",
|
||||||
|
"integrity": "sha1-6nrd907Ow9dimCegw54smt3HPQQ=",
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@ionic-native/in-app-browser": {
|
"@ionic-native/in-app-browser": {
|
||||||
@@ -2618,6 +2670,14 @@
|
|||||||
"optional": true,
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/cordova": "^0.0.34"
|
"@types/cordova": "^0.0.34"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@types/cordova": {
|
||||||
|
"version": "0.0.34",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/cordova/-/cordova-0.0.34.tgz",
|
||||||
|
"integrity": "sha1-6nrd907Ow9dimCegw54smt3HPQQ=",
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@ionic-native/network": {
|
"@ionic-native/network": {
|
||||||
@@ -2626,6 +2686,13 @@
|
|||||||
"integrity": "sha512-gpa7cJqodEK+zmmViYJCqEpXoKSXcaYLaaRKdv5gn5M++bpmiw2pKM9JH8VoqYWaYDcUwD3S0yYeBBkG5DE0Kg==",
|
"integrity": "sha512-gpa7cJqodEK+zmmViYJCqEpXoKSXcaYLaaRKdv5gn5M++bpmiw2pKM9JH8VoqYWaYDcUwD3S0yYeBBkG5DE0Kg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/cordova": "^0.0.34"
|
"@types/cordova": "^0.0.34"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@types/cordova": {
|
||||||
|
"version": "0.0.34",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/cordova/-/cordova-0.0.34.tgz",
|
||||||
|
"integrity": "sha1-6nrd907Ow9dimCegw54smt3HPQQ="
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@ionic-native/safari-view-controller": {
|
"@ionic-native/safari-view-controller": {
|
||||||
@@ -2635,6 +2702,14 @@
|
|||||||
"optional": true,
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/cordova": "^0.0.34"
|
"@types/cordova": "^0.0.34"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@types/cordova": {
|
||||||
|
"version": "0.0.34",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/cordova/-/cordova-0.0.34.tgz",
|
||||||
|
"integrity": "sha1-6nrd907Ow9dimCegw54smt3HPQQ=",
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@ionic-native/secure-storage": {
|
"@ionic-native/secure-storage": {
|
||||||
@@ -2644,6 +2719,14 @@
|
|||||||
"optional": true,
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/cordova": "^0.0.34"
|
"@types/cordova": "^0.0.34"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@types/cordova": {
|
||||||
|
"version": "0.0.34",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/cordova/-/cordova-0.0.34.tgz",
|
||||||
|
"integrity": "sha1-6nrd907Ow9dimCegw54smt3HPQQ=",
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@ionic/angular": {
|
"@ionic/angular": {
|
||||||
@@ -3884,11 +3967,6 @@
|
|||||||
"integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==",
|
"integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@types/cordova": {
|
|
||||||
"version": "0.0.34",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/cordova/-/cordova-0.0.34.tgz",
|
|
||||||
"integrity": "sha1-6nrd907Ow9dimCegw54smt3HPQQ="
|
|
||||||
},
|
|
||||||
"@types/cors": {
|
"@types/cors": {
|
||||||
"version": "2.8.12",
|
"version": "2.8.12",
|
||||||
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz",
|
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz",
|
||||||
@@ -5481,6 +5559,16 @@
|
|||||||
"integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
|
"integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"bindings": {
|
||||||
|
"version": "1.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
|
||||||
|
"integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"file-uri-to-path": "1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"bl": {
|
"bl": {
|
||||||
"version": "4.1.0",
|
"version": "4.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
|
||||||
@@ -9377,6 +9465,13 @@
|
|||||||
"flat-cache": "^3.0.4"
|
"flat-cache": "^3.0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"file-uri-to-path": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"filelist": {
|
"filelist": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.2.tgz",
|
||||||
@@ -15863,12 +15958,6 @@
|
|||||||
"ipaddr.js": "1.9.1"
|
"ipaddr.js": "1.9.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"proxy-middleware": {
|
|
||||||
"version": "0.15.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/proxy-middleware/-/proxy-middleware-0.15.0.tgz",
|
|
||||||
"integrity": "sha1-o/3xvvtzD5UZZYcqwvYHTGFHelY=",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"prr": {
|
"prr": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
|
||||||
@@ -19505,6 +19594,7 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
|
"bindings": "^1.5.0",
|
||||||
"nan": "^2.12.1"
|
"nan": "^2.12.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -204,7 +204,7 @@ const sampleBooks: SCBook[] = [
|
|||||||
type: SCThingOriginType.Remote,
|
type: SCThingOriginType.Remote,
|
||||||
},
|
},
|
||||||
type: SCThingType.Book,
|
type: SCThingType.Book,
|
||||||
uid: 'book-123',
|
uid: 'HEB290615194',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
authors: [],
|
authors: [],
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ import {CatalogModule} from './modules/catalog/catalog.module';
|
|||||||
import {ConfigModule} from './modules/config/config.module';
|
import {ConfigModule} from './modules/config/config.module';
|
||||||
import {ConfigProvider} from './modules/config/config.provider';
|
import {ConfigProvider} from './modules/config/config.provider';
|
||||||
import {DataModule} from './modules/data/data.module';
|
import {DataModule} from './modules/data/data.module';
|
||||||
|
import {HebisModule} from './modules/hebis/hebis.module';
|
||||||
import {MapModule} from './modules/map/map.module';
|
import {MapModule} from './modules/map/map.module';
|
||||||
import {MenuModule} from './modules/menu/menu.module';
|
import {MenuModule} from './modules/menu/menu.module';
|
||||||
import {NewsModule} from './modules/news/news.module';
|
import {NewsModule} from './modules/news/news.module';
|
||||||
@@ -153,6 +154,7 @@ const providers: Provider[] = [
|
|||||||
CommonModule,
|
CommonModule,
|
||||||
ConfigModule,
|
ConfigModule,
|
||||||
DataModule,
|
DataModule,
|
||||||
|
HebisModule,
|
||||||
EndSessionPageModule,
|
EndSessionPageModule,
|
||||||
IonicModule.forRoot(),
|
IonicModule.forRoot(),
|
||||||
FavoritesModule,
|
FavoritesModule,
|
||||||
|
|||||||
@@ -182,6 +182,9 @@ import {TitleCardComponent} from './elements/title-card.component';
|
|||||||
SkeletonSimpleCardComponent,
|
SkeletonSimpleCardComponent,
|
||||||
SearchPageComponent,
|
SearchPageComponent,
|
||||||
SimpleDataListComponent,
|
SimpleDataListComponent,
|
||||||
|
ArticleDetailContentComponent,
|
||||||
|
OriginDetailComponent,
|
||||||
|
FavoriteButtonComponent,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class DataModule {}
|
export class DataModule {}
|
||||||
|
|||||||
@@ -66,9 +66,9 @@ export class DataDetailComponent {
|
|||||||
* @param translateService he translate provider
|
* @param translateService he translate provider
|
||||||
*/
|
*/
|
||||||
constructor(
|
constructor(
|
||||||
private readonly route: ActivatedRoute,
|
protected readonly route: ActivatedRoute,
|
||||||
private readonly dataProvider: DataProvider,
|
private readonly dataProvider: DataProvider,
|
||||||
private readonly network: Network,
|
protected readonly network: Network,
|
||||||
private readonly favoritesService: FavoritesService,
|
private readonly favoritesService: FavoritesService,
|
||||||
translateService: TranslateService,
|
translateService: TranslateService,
|
||||||
) {
|
) {
|
||||||
@@ -125,9 +125,7 @@ export class DataDetailComponent {
|
|||||||
* @param refresher Refresher component that triggers the update
|
* @param refresher Refresher component that triggers the update
|
||||||
*/
|
*/
|
||||||
async refresh(refresher: IonRefresher) {
|
async refresh(refresher: IonRefresher) {
|
||||||
await this.getItem(
|
await this.getItem(this.route.snapshot.paramMap.get('uid') ?? '');
|
||||||
this.item?.uid ?? this.route.snapshot.paramMap.get('uid') ?? '',
|
|
||||||
);
|
|
||||||
await refresher.complete();
|
await refresher.complete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,17 +13,24 @@
|
|||||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
import {Component, OnInit} from '@angular/core';
|
import {Component, OnInit} from '@angular/core';
|
||||||
|
import {AlertController} from '@ionic/angular';
|
||||||
|
import {Router} from '@angular/router';
|
||||||
|
import {NGXLogger} from 'ngx-logger';
|
||||||
|
import {
|
||||||
|
debounceTime,
|
||||||
|
distinctUntilChanged,
|
||||||
|
startWith,
|
||||||
|
take,
|
||||||
|
} from 'rxjs/operators';
|
||||||
|
import {combineLatest} from 'rxjs';
|
||||||
|
import {SCThingType} from '@openstapps/core';
|
||||||
import {FavoritesService} from './favorites.service';
|
import {FavoritesService} from './favorites.service';
|
||||||
import {DataRoutingService} from '../data/data-routing.service';
|
import {DataRoutingService} from '../data/data-routing.service';
|
||||||
import {Router} from '@angular/router';
|
|
||||||
import {ContextMenuService} from '../menu/context/context-menu.service';
|
import {ContextMenuService} from '../menu/context/context-menu.service';
|
||||||
import {SearchPageComponent} from '../data/list/search-page.component';
|
import {SearchPageComponent} from '../data/list/search-page.component';
|
||||||
import {AlertController} from '@ionic/angular';
|
|
||||||
import {DataProvider} from '../data/data.provider';
|
import {DataProvider} from '../data/data.provider';
|
||||||
import {SettingsProvider} from '../settings/settings.provider';
|
import {SettingsProvider} from '../settings/settings.provider';
|
||||||
import {NGXLogger} from 'ngx-logger';
|
|
||||||
import {PositionService} from '../map/position.service';
|
import {PositionService} from '../map/position.service';
|
||||||
import {take} from 'rxjs/operators';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The page for showing favorites
|
* The page for showing favorites
|
||||||
@@ -62,9 +69,69 @@ export class FavoritesPageComponent
|
|||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
super.ngOnInit();
|
super.ngOnInit();
|
||||||
|
for (const subscription of this.subscriptions) {
|
||||||
|
subscription.unsubscribe();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recreate subscriptions to handle different routing
|
||||||
this.subscriptions.push(
|
this.subscriptions.push(
|
||||||
this.favoritesService.favoritesChanged$.subscribe(_favoritesMap => {
|
combineLatest([
|
||||||
this.fetchAndUpdateItems();
|
this.queryTextChanged.pipe(
|
||||||
|
debounceTime(this.searchQueryDueTime),
|
||||||
|
distinctUntilChanged(),
|
||||||
|
startWith(this.queryText),
|
||||||
|
),
|
||||||
|
this.contextMenuService.filterQueryChanged$.pipe(
|
||||||
|
startWith(this.filterQuery),
|
||||||
|
),
|
||||||
|
this.contextMenuService.sortQueryChanged$.pipe(
|
||||||
|
startWith(this.sortQuery),
|
||||||
|
),
|
||||||
|
this.favoritesService.favoritesChanged$,
|
||||||
|
]).subscribe(async query => {
|
||||||
|
this.queryText = query[0];
|
||||||
|
this.filterQuery = query[1];
|
||||||
|
this.sortQuery = query[2];
|
||||||
|
this.from = 0;
|
||||||
|
if (
|
||||||
|
typeof this.filterQuery !== 'undefined' ||
|
||||||
|
this.queryText?.length > 0 ||
|
||||||
|
this.showDefaultData
|
||||||
|
) {
|
||||||
|
await this.fetchAndUpdateItems();
|
||||||
|
this.queryChanged.next();
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
this.settingsProvider.settingsActionChanged$.subscribe(
|
||||||
|
({type, payload}) => {
|
||||||
|
if (type === 'stapps.settings.changed') {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||||
|
const {category, name, value} = payload!;
|
||||||
|
this.logger.log(`received event "settings.changed" with category:
|
||||||
|
${category}, name: ${name}, value: ${JSON.stringify(value)}`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
this.dataRoutingService.itemSelectListener().subscribe(item => {
|
||||||
|
if (this.itemRouting) {
|
||||||
|
if (
|
||||||
|
[
|
||||||
|
SCThingType.Book,
|
||||||
|
SCThingType.Periodical,
|
||||||
|
SCThingType.Article,
|
||||||
|
].includes(item.type)
|
||||||
|
) {
|
||||||
|
void this.router.navigate([
|
||||||
|
'hebis-detail',
|
||||||
|
(item.origin &&
|
||||||
|
'originalId' in item.origin &&
|
||||||
|
item.origin['originalId']) ||
|
||||||
|
'',
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
void this.router.navigate(['data-detail', item.uid]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,138 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-non-null-assertion,@typescript-eslint/no-explicit-any */
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2018, 2019 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
import {CUSTOM_ELEMENTS_SCHEMA} from '@angular/core';
|
||||||
|
import {ComponentFixture, TestBed, waitForAsync} from '@angular/core/testing';
|
||||||
|
import {ActivatedRoute, RouterModule} from '@angular/router';
|
||||||
|
import {IonRefresher} from '@ionic/angular';
|
||||||
|
import {
|
||||||
|
TranslateLoader,
|
||||||
|
TranslateModule,
|
||||||
|
TranslateService,
|
||||||
|
} from '@ngx-translate/core';
|
||||||
|
import {sampleThingsMap} from '../../../_helpers/data/sample-things';
|
||||||
|
import {HebisRoutingModule} from '../hebis-routing.module';
|
||||||
|
import {HebisModule} from '../hebis.module';
|
||||||
|
import {DaiaAvailabilityComponent} from './daia-availability.component';
|
||||||
|
import {Observable, of} from 'rxjs';
|
||||||
|
import {StorageProvider} from '../../storage/storage.provider';
|
||||||
|
import {DaiaDataProvider} from '../daia-data.provider';
|
||||||
|
|
||||||
|
const translations: any = {data: {detail: {TITLE: 'Foo'}}};
|
||||||
|
|
||||||
|
class TranslateFakeLoader implements TranslateLoader {
|
||||||
|
getTranslation(_lang: string): Observable<any> {
|
||||||
|
return of(translations);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('DaiaAvailabilityComponent', () => {
|
||||||
|
let comp: DaiaAvailabilityComponent;
|
||||||
|
let fixture: ComponentFixture<DaiaAvailabilityComponent>;
|
||||||
|
let dataProvider: DaiaDataProvider;
|
||||||
|
let refresher: IonRefresher;
|
||||||
|
const sampleThing = sampleThingsMap.book[0];
|
||||||
|
let translateService: TranslateService;
|
||||||
|
|
||||||
|
// @Component({ selector: 'stapps-data-list-item', template: '' })
|
||||||
|
// class DataListItemComponent {
|
||||||
|
// @Input() item;
|
||||||
|
// }
|
||||||
|
|
||||||
|
const fakeActivatedRoute = {
|
||||||
|
snapshot: {
|
||||||
|
paramMap: {
|
||||||
|
get: () => {
|
||||||
|
return sampleThing.uid;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const storageProviderSpy = jasmine.createSpyObj('StorageProvider', [
|
||||||
|
'init',
|
||||||
|
'get',
|
||||||
|
'has',
|
||||||
|
'put',
|
||||||
|
'search',
|
||||||
|
]);
|
||||||
|
|
||||||
|
beforeEach(
|
||||||
|
waitForAsync(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
imports: [
|
||||||
|
RouterModule.forRoot([], {relativeLinkResolution: 'legacy'}),
|
||||||
|
HebisRoutingModule,
|
||||||
|
HebisModule,
|
||||||
|
TranslateModule.forRoot({
|
||||||
|
loader: {provide: TranslateLoader, useClass: TranslateFakeLoader},
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
providers: [
|
||||||
|
{
|
||||||
|
provide: ActivatedRoute,
|
||||||
|
useValue: fakeActivatedRoute,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: StorageProvider,
|
||||||
|
useValue: storageProviderSpy,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||||
|
}).compileComponents();
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
dataProvider = TestBed.get(DaiaDataProvider);
|
||||||
|
translateService = TestBed.get(TranslateService);
|
||||||
|
refresher = jasmine.createSpyObj('refresher', ['complete']);
|
||||||
|
spyOn(dataProvider, 'get' as any).and.returnValue(
|
||||||
|
Promise.resolve(sampleThing),
|
||||||
|
);
|
||||||
|
spyOn(
|
||||||
|
DaiaAvailabilityComponent.prototype,
|
||||||
|
'getAvailability',
|
||||||
|
).and.callThrough();
|
||||||
|
fixture = await TestBed.createComponent(DaiaAvailabilityComponent);
|
||||||
|
comp = fixture.componentInstance;
|
||||||
|
translateService.use('foo');
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create component', () => expect(comp).toBeDefined());
|
||||||
|
|
||||||
|
it('should get the availability of an item', () => {
|
||||||
|
comp.getAvailability(sampleThing.uid);
|
||||||
|
expect(
|
||||||
|
DaiaAvailabilityComponent.prototype.getAvailability,
|
||||||
|
).toHaveBeenCalledWith(sampleThing.uid);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should get the availability of an item when the view is entered', () => {
|
||||||
|
comp.ngOnInit();
|
||||||
|
expect(
|
||||||
|
DaiaAvailabilityComponent.prototype.getAvailability,
|
||||||
|
).toHaveBeenCalledWith(sampleThing.uid);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should update the data item when refresh is called', async () => {
|
||||||
|
await comp.refresh(refresher);
|
||||||
|
expect(
|
||||||
|
DaiaAvailabilityComponent.prototype.getAvailability,
|
||||||
|
).toHaveBeenCalledWith(sampleThing.uid);
|
||||||
|
expect(refresher.complete).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018, 2019 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
import {Component, OnInit} from '@angular/core';
|
||||||
|
import {ActivatedRoute} from '@angular/router';
|
||||||
|
import {Network} from '@ionic-native/network/ngx';
|
||||||
|
import {TranslateService} from '@ngx-translate/core';
|
||||||
|
import {SCUuid} from '@openstapps/core';
|
||||||
|
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';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Component to display an SCThing detailed
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: 'stapps-daia-availability',
|
||||||
|
styleUrls: ['daia-availability.scss'],
|
||||||
|
templateUrl: 'daia-availability.html',
|
||||||
|
})
|
||||||
|
export class DaiaAvailabilityComponent
|
||||||
|
extends DataDetailComponent
|
||||||
|
implements OnInit
|
||||||
|
{
|
||||||
|
holdings: SCDaiaHoldings[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param route the route the page was accessed from
|
||||||
|
* @param dataProvider the data provider
|
||||||
|
* @param network the network provider
|
||||||
|
* @param favoritesService the favorites provider
|
||||||
|
* @param translateService he translate provider
|
||||||
|
* @param daiaDataProvider DaiaDataProvider
|
||||||
|
*/
|
||||||
|
constructor(
|
||||||
|
route: ActivatedRoute,
|
||||||
|
dataProvider: DataProvider,
|
||||||
|
network: Network,
|
||||||
|
favoritesService: FavoritesService,
|
||||||
|
translateService: TranslateService,
|
||||||
|
private daiaDataProvider: DaiaDataProvider,
|
||||||
|
) {
|
||||||
|
super(route, dataProvider, network, favoritesService, translateService);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if we have internet
|
||||||
|
*/
|
||||||
|
isDisconnected(): boolean {
|
||||||
|
return this.network.type === this.network.Connection.NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize
|
||||||
|
*/
|
||||||
|
async ngOnInit() {
|
||||||
|
const uid = this.route.snapshot.paramMap.get('uid') || '';
|
||||||
|
await this.getAvailability(uid ?? '');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides data item with given UID
|
||||||
|
*
|
||||||
|
* @param uid Unique identifier of a thing
|
||||||
|
*/
|
||||||
|
async getAvailability(uid: SCUuid) {
|
||||||
|
this.daiaDataProvider.getAvailability(uid).then(holdings => {
|
||||||
|
this.holdings = holdings;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
<ion-card>
|
||||||
|
<ion-card-header>{{
|
||||||
|
'hebisSearch.daia.availability' | translate
|
||||||
|
}}</ion-card-header>
|
||||||
|
<ion-card-content>
|
||||||
|
<ng-container *ngFor="let holding of holdings">
|
||||||
|
<ion-label
|
||||||
|
><a [href]="holding.href" target="_blank">{{
|
||||||
|
holding.label
|
||||||
|
}}</a></ion-label
|
||||||
|
>
|
||||||
|
<ion-grid>
|
||||||
|
<ion-row *ngIf="holding.signature">
|
||||||
|
<ion-col size="3">{{
|
||||||
|
'hebisSearch.daia.signature' | translate
|
||||||
|
}}</ion-col>
|
||||||
|
<ion-col
|
||||||
|
size="9"
|
||||||
|
*ngIf="
|
||||||
|
!holding ||
|
||||||
|
!holding.available ||
|
||||||
|
holding.available.service !== 'openaccess'
|
||||||
|
"
|
||||||
|
>{{ holding.signature }}</ion-col
|
||||||
|
>
|
||||||
|
<ion-col size="9" *ngIf="holding.available.service === 'openaccess'">
|
||||||
|
<a [href]="holding.available.href" target="_blank">{{
|
||||||
|
'hebisSearch.daia.ejournal' | translate
|
||||||
|
}}</a>
|
||||||
|
</ion-col>
|
||||||
|
</ion-row>
|
||||||
|
<ion-row *ngIf="holding.storage && holding.storage.content">
|
||||||
|
<ion-col size="3">{{
|
||||||
|
'hebisSearch.daia.location' | translate
|
||||||
|
}}</ion-col>
|
||||||
|
<ion-col size="9" [innerHTML]="holding.storage.content"></ion-col>
|
||||||
|
</ion-row>
|
||||||
|
<ion-row *ngIf="holding.about">
|
||||||
|
<ion-col size="3">{{
|
||||||
|
'hebisSearch.daia.comment' | translate
|
||||||
|
}}</ion-col>
|
||||||
|
<ion-col size="9">{{ holding.about }}</ion-col>
|
||||||
|
</ion-row>
|
||||||
|
<ion-row
|
||||||
|
*ngIf="holding.available && holding.available.service === 'loan'"
|
||||||
|
>
|
||||||
|
<ion-col size="3">{{
|
||||||
|
'hebisSearch.daia.status' | translate
|
||||||
|
}}</ion-col>
|
||||||
|
<ion-col size="9"
|
||||||
|
>{{ 'hebisSearch.daia.available' | translate }}
|
||||||
|
<a
|
||||||
|
[href]="holding.available.href"
|
||||||
|
*ngIf="holding.available.href"
|
||||||
|
target="_blank"
|
||||||
|
>{{ 'hebisSearch.daia.order' | translate }}</a
|
||||||
|
></ion-col
|
||||||
|
>
|
||||||
|
</ion-row>
|
||||||
|
</ion-grid>
|
||||||
|
</ng-container>
|
||||||
|
</ion-card-content>
|
||||||
|
</ion-card>
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
ion-card {
|
||||||
|
margin: 0;
|
||||||
|
box-shadow: none;
|
||||||
|
ion-card-content {
|
||||||
|
h1 {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
padding-bottom: 8px;
|
||||||
|
}
|
||||||
|
ion-card-header {
|
||||||
|
color: var(--ion-color-dark);
|
||||||
|
padding-top: 8px;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
121
src/app/modules/hebis/daia-data.provider.ts
Normal file
121
src/app/modules/hebis/daia-data.provider.ts
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018-2021 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
import {Injectable} from '@angular/core';
|
||||||
|
import {Client} from '@openstapps/api/lib/client';
|
||||||
|
import {SCDaiaAvailabilityResponse, SCDaiaHoldings} from './protocol/response';
|
||||||
|
import {StorageProvider} from '../storage/storage.provider';
|
||||||
|
import {StAppsWebHttpClient} from '../data/stapps-web-http-client.provider';
|
||||||
|
import {HttpClient} from '@angular/common/http';
|
||||||
|
import {DataProvider} from '../data/data.provider';
|
||||||
|
import {environment} from '../../../environments/environment';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generated class for the DataProvider provider.
|
||||||
|
*
|
||||||
|
* See https://angular.io/guide/dependency-injection for more info on providers
|
||||||
|
* and Angular DI.
|
||||||
|
*/
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root',
|
||||||
|
})
|
||||||
|
export class DaiaDataProvider extends DataProvider {
|
||||||
|
/**
|
||||||
|
* TODO
|
||||||
|
*/
|
||||||
|
storageProvider: StorageProvider;
|
||||||
|
|
||||||
|
httpClient: HttpClient;
|
||||||
|
|
||||||
|
backendUrl = environment.daia_url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO
|
||||||
|
*
|
||||||
|
* @param stAppsWebHttpClient TODO
|
||||||
|
* @param storageProvider TODO
|
||||||
|
* @param httpClient TODO
|
||||||
|
*/
|
||||||
|
constructor(
|
||||||
|
stAppsWebHttpClient: StAppsWebHttpClient,
|
||||||
|
storageProvider: StorageProvider,
|
||||||
|
httpClient: HttpClient,
|
||||||
|
) {
|
||||||
|
super(stAppsWebHttpClient, storageProvider);
|
||||||
|
this.storageProvider = storageProvider;
|
||||||
|
this.httpClient = httpClient;
|
||||||
|
this.client = new Client(
|
||||||
|
stAppsWebHttpClient,
|
||||||
|
this.backendUrl,
|
||||||
|
this.appVersion,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async getAvailability(id: string): Promise<SCDaiaHoldings[]> {
|
||||||
|
return new Promise(resolve =>
|
||||||
|
this.httpClient
|
||||||
|
.get<SCDaiaAvailabilityResponse>(this.backendUrl, {params: {id}})
|
||||||
|
.subscribe((response: SCDaiaAvailabilityResponse) => {
|
||||||
|
console.error(response);
|
||||||
|
const holdings: SCDaiaHoldings[] = [];
|
||||||
|
if (response && Array.isArray(response.document)) {
|
||||||
|
response.document.map(document => {
|
||||||
|
Array.isArray(document.item) &&
|
||||||
|
document.item.map(element => {
|
||||||
|
try {
|
||||||
|
const {
|
||||||
|
department: {
|
||||||
|
id: departmentId,
|
||||||
|
content: departmentLabel,
|
||||||
|
href: departmentLink,
|
||||||
|
} = {id: 'noDep', content: '', href: ''},
|
||||||
|
label,
|
||||||
|
about,
|
||||||
|
available,
|
||||||
|
storage,
|
||||||
|
} = element;
|
||||||
|
const holdingIndex = holdings.findIndex(
|
||||||
|
holding => holding.id === departmentId,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (holdingIndex === -1) {
|
||||||
|
holdings.push({
|
||||||
|
id: departmentId,
|
||||||
|
label: departmentLabel,
|
||||||
|
href: departmentLink,
|
||||||
|
signature: label,
|
||||||
|
available:
|
||||||
|
(Array.isArray(available) &&
|
||||||
|
(available.find(
|
||||||
|
item => item.service === 'openaccess',
|
||||||
|
) ||
|
||||||
|
available.find(
|
||||||
|
item => item.service === 'loan',
|
||||||
|
))) ||
|
||||||
|
undefined,
|
||||||
|
storage,
|
||||||
|
about,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// No element available
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
resolve(holdings);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
104
src/app/modules/hebis/hebis-data.provider.ts
Normal file
104
src/app/modules/hebis/hebis-data.provider.ts
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018-2021 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
import {Injectable} from '@angular/core';
|
||||||
|
import {Client} from '@openstapps/api/lib/client';
|
||||||
|
import {SCHebisSearchRequest} from './protocol/request';
|
||||||
|
import {SCHebisSearchResponse} from './protocol/response';
|
||||||
|
import {StorageProvider} from '../storage/storage.provider';
|
||||||
|
import {StAppsWebHttpClient} from '../data/stapps-web-http-client.provider';
|
||||||
|
import {HttpClient} from '@angular/common/http';
|
||||||
|
import {DataProvider} from '../data/data.provider';
|
||||||
|
import {SCHebisSearchRoute} from './protocol/route';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generated class for the DataProvider provider.
|
||||||
|
*
|
||||||
|
* See https://angular.io/guide/dependency-injection for more info on providers
|
||||||
|
* and Angular DI.
|
||||||
|
*/
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root',
|
||||||
|
})
|
||||||
|
export class HebisDataProvider extends DataProvider {
|
||||||
|
/**
|
||||||
|
* TODO
|
||||||
|
*/
|
||||||
|
storageProvider: StorageProvider;
|
||||||
|
|
||||||
|
httpClient: HttpClient;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instance of hebis search request route
|
||||||
|
*/
|
||||||
|
private readonly hebisSearchRoute = new SCHebisSearchRoute();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO
|
||||||
|
*
|
||||||
|
* @param stAppsWebHttpClient TODO
|
||||||
|
* @param storageProvider TODO
|
||||||
|
* @param httpClient TODO
|
||||||
|
*/
|
||||||
|
constructor(
|
||||||
|
stAppsWebHttpClient: StAppsWebHttpClient,
|
||||||
|
storageProvider: StorageProvider,
|
||||||
|
httpClient: HttpClient,
|
||||||
|
) {
|
||||||
|
super(stAppsWebHttpClient, storageProvider);
|
||||||
|
this.storageProvider = storageProvider;
|
||||||
|
this.httpClient = httpClient;
|
||||||
|
this.client = new Client(
|
||||||
|
stAppsWebHttpClient,
|
||||||
|
this.backendUrl,
|
||||||
|
this.appVersion,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a search request to the backend
|
||||||
|
*
|
||||||
|
* All results will be returned if no size is set in the request.
|
||||||
|
*
|
||||||
|
* @param searchRequest Search request
|
||||||
|
*/
|
||||||
|
async hebisSearch(
|
||||||
|
searchRequest: SCHebisSearchRequest,
|
||||||
|
): Promise<SCHebisSearchResponse> {
|
||||||
|
let page: number | undefined = searchRequest.page;
|
||||||
|
|
||||||
|
if (typeof page === 'undefined') {
|
||||||
|
const preFlightResponse =
|
||||||
|
await this.client.invokeRoute<SCHebisSearchResponse>(
|
||||||
|
this.hebisSearchRoute,
|
||||||
|
undefined,
|
||||||
|
{
|
||||||
|
...searchRequest,
|
||||||
|
page: 0,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
page = preFlightResponse.pagination.total;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.client.invokeRoute<SCHebisSearchResponse>(
|
||||||
|
this.hebisSearchRoute,
|
||||||
|
undefined,
|
||||||
|
{
|
||||||
|
...searchRequest,
|
||||||
|
page,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2019 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
import {Component, Input} from '@angular/core';
|
||||||
|
import {SCThings} from '@openstapps/core';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: 'stapps-hebis-detail-content',
|
||||||
|
styleUrls: ['hebis-detail-content.scss'],
|
||||||
|
templateUrl: 'hebis-detail-content.html',
|
||||||
|
})
|
||||||
|
export class HebisDetailContentComponent {
|
||||||
|
/**
|
||||||
|
* TODO
|
||||||
|
*/
|
||||||
|
@Input() item: SCThings;
|
||||||
|
}
|
||||||
36
src/app/modules/hebis/hebis-detail/hebis-detail-content.html
Normal file
36
src/app/modules/hebis/hebis-detail/hebis-detail-content.html
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
<div [ngSwitch]="item.type">
|
||||||
|
<stapps-book-detail-content
|
||||||
|
[item]="item"
|
||||||
|
*ngSwitchCase="'book'"
|
||||||
|
></stapps-book-detail-content>
|
||||||
|
<stapps-periodical-detail-content
|
||||||
|
[item]="item"
|
||||||
|
*ngSwitchCase="'periodical'"
|
||||||
|
></stapps-periodical-detail-content>
|
||||||
|
<stapps-hebis-article-content
|
||||||
|
[item]="item"
|
||||||
|
*ngSwitchCase="'article'"
|
||||||
|
></stapps-hebis-article-content>
|
||||||
|
<ng-container *ngSwitchDefault>
|
||||||
|
<ion-item class="ion-text-wrap" lines="inset">
|
||||||
|
<ion-thumbnail slot="start" class="ion-margin-end">
|
||||||
|
<ion-icon color="medium" [attr.name]="item.type | dataIcon"></ion-icon>
|
||||||
|
</ion-thumbnail>
|
||||||
|
<ion-grid>
|
||||||
|
<ion-row>
|
||||||
|
<ion-col>
|
||||||
|
<div class="ion-text-wrap">
|
||||||
|
<h2 class="name">{{ item.name }}</h2>
|
||||||
|
<ion-note>{{ item.type }}</ion-note>
|
||||||
|
</div>
|
||||||
|
</ion-col>
|
||||||
|
</ion-row>
|
||||||
|
</ion-grid>
|
||||||
|
</ion-item>
|
||||||
|
<stapps-simple-card
|
||||||
|
*ngIf="item.description"
|
||||||
|
[title]="'description' | propertyNameTranslate: item | titlecase"
|
||||||
|
[content]="'description' | thingTranslate: item"
|
||||||
|
></stapps-simple-card>
|
||||||
|
</ng-container>
|
||||||
|
</div>
|
||||||
28
src/app/modules/hebis/hebis-detail/hebis-detail-content.scss
Normal file
28
src/app/modules/hebis/hebis-detail/hebis-detail-content.scss
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
:host ::ng-deep {
|
||||||
|
ion-card {
|
||||||
|
margin: 0;
|
||||||
|
box-shadow: none;
|
||||||
|
ion-card-content {
|
||||||
|
h1 {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
padding-bottom: 8px;
|
||||||
|
}
|
||||||
|
ion-card-header {
|
||||||
|
color: var(--ion-color-dark);
|
||||||
|
padding-top: 8px;
|
||||||
|
padding-bottom: 4px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
ion-grid, ion-col {
|
||||||
|
padding-inline-start: 0;
|
||||||
|
padding-top: 0;
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ion-grid, ion-col {
|
||||||
|
padding-inline-start: 0;
|
||||||
|
padding-top: 0;
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,135 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-non-null-assertion,@typescript-eslint/no-explicit-any */
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2018, 2019 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
import {CUSTOM_ELEMENTS_SCHEMA} from '@angular/core';
|
||||||
|
import {ComponentFixture, TestBed, waitForAsync} from '@angular/core/testing';
|
||||||
|
import {ActivatedRoute, RouterModule} from '@angular/router';
|
||||||
|
import {IonRefresher} from '@ionic/angular';
|
||||||
|
import {
|
||||||
|
TranslateLoader,
|
||||||
|
TranslateModule,
|
||||||
|
TranslateService,
|
||||||
|
} from '@ngx-translate/core';
|
||||||
|
import {sampleThingsMap} from '../../../_helpers/data/sample-things';
|
||||||
|
import {HebisRoutingModule} from '../hebis-routing.module';
|
||||||
|
import {HebisModule} from '../hebis.module';
|
||||||
|
import {HebisDataProvider} from '../hebis-data.provider';
|
||||||
|
import {HebisDetailComponent} from './hebis-detail.component';
|
||||||
|
import {Observable, of} from 'rxjs';
|
||||||
|
import {StorageProvider} from '../../storage/storage.provider';
|
||||||
|
|
||||||
|
const translations: any = {data: {detail: {TITLE: 'Foo'}}};
|
||||||
|
|
||||||
|
class TranslateFakeLoader implements TranslateLoader {
|
||||||
|
getTranslation(_lang: string): Observable<any> {
|
||||||
|
return of(translations);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('HebisDetailComponent', () => {
|
||||||
|
let comp: HebisDetailComponent;
|
||||||
|
let fixture: ComponentFixture<HebisDetailComponent>;
|
||||||
|
let dataProvider: HebisDataProvider;
|
||||||
|
let refresher: IonRefresher;
|
||||||
|
const sampleThing = sampleThingsMap.book[0];
|
||||||
|
let translateService: TranslateService;
|
||||||
|
|
||||||
|
// @Component({ selector: 'stapps-data-list-item', template: '' })
|
||||||
|
// class DataListItemComponent {
|
||||||
|
// @Input() item;
|
||||||
|
// }
|
||||||
|
|
||||||
|
const fakeActivatedRoute = {
|
||||||
|
snapshot: {
|
||||||
|
paramMap: {
|
||||||
|
get: () => {
|
||||||
|
return sampleThing.uid;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const storageProviderSpy = jasmine.createSpyObj('StorageProvider', [
|
||||||
|
'init',
|
||||||
|
'get',
|
||||||
|
'has',
|
||||||
|
'put',
|
||||||
|
'search',
|
||||||
|
]);
|
||||||
|
|
||||||
|
beforeEach(
|
||||||
|
waitForAsync(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
imports: [
|
||||||
|
RouterModule.forRoot([], {relativeLinkResolution: 'legacy'}),
|
||||||
|
HebisRoutingModule,
|
||||||
|
HebisModule,
|
||||||
|
TranslateModule.forRoot({
|
||||||
|
loader: {provide: TranslateLoader, useClass: TranslateFakeLoader},
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
providers: [
|
||||||
|
{
|
||||||
|
provide: ActivatedRoute,
|
||||||
|
useValue: fakeActivatedRoute,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: StorageProvider,
|
||||||
|
useValue: storageProviderSpy,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||||
|
}).compileComponents();
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
dataProvider = TestBed.get(HebisDataProvider);
|
||||||
|
translateService = TestBed.get(TranslateService);
|
||||||
|
refresher = jasmine.createSpyObj('refresher', ['complete']);
|
||||||
|
spyOn(dataProvider, 'get' as any).and.returnValue(
|
||||||
|
Promise.resolve(sampleThing),
|
||||||
|
);
|
||||||
|
spyOn(HebisDetailComponent.prototype, 'getItem').and.callThrough();
|
||||||
|
fixture = await TestBed.createComponent(HebisDetailComponent);
|
||||||
|
comp = fixture.componentInstance;
|
||||||
|
translateService.use('foo');
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create component', () => expect(comp).toBeDefined());
|
||||||
|
|
||||||
|
it('should get a data item', () => {
|
||||||
|
comp.getItem(sampleThing.uid);
|
||||||
|
expect(HebisDetailComponent.prototype.getItem).toHaveBeenCalledWith(
|
||||||
|
sampleThing.uid,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should get a data item when the view is entered', () => {
|
||||||
|
comp.ionViewWillEnter();
|
||||||
|
expect(HebisDetailComponent.prototype.getItem).toHaveBeenCalledWith(
|
||||||
|
sampleThing.uid,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should update the data item when refresh is called', async () => {
|
||||||
|
await comp.refresh(refresher);
|
||||||
|
expect(HebisDetailComponent.prototype.getItem).toHaveBeenCalledWith(
|
||||||
|
sampleThing.uid,
|
||||||
|
);
|
||||||
|
expect(refresher.complete).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
83
src/app/modules/hebis/hebis-detail/hebis-detail.component.ts
Normal file
83
src/app/modules/hebis/hebis-detail/hebis-detail.component.ts
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018, 2019 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
import {Component} from '@angular/core';
|
||||||
|
import {ActivatedRoute} from '@angular/router';
|
||||||
|
import {Network} from '@ionic-native/network/ngx';
|
||||||
|
import {TranslateService} from '@ngx-translate/core';
|
||||||
|
import {SCUuid} from '@openstapps/core';
|
||||||
|
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';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Component to display an SCThing detailed
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: 'stapps-hebis-detail',
|
||||||
|
styleUrls: ['hebis-detail.scss'],
|
||||||
|
templateUrl: 'hebis-detail.html',
|
||||||
|
})
|
||||||
|
export class HebisDetailComponent extends DataDetailComponent {
|
||||||
|
holdings: SCDaiaHoldings[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param route the route the page was accessed from
|
||||||
|
* @param dataProvider the data provider
|
||||||
|
* @param network the network provider
|
||||||
|
* @param favoritesService the favorites provider
|
||||||
|
* @param translateService he translate provider
|
||||||
|
* @param hebisDataProvider HebisDataProvider
|
||||||
|
*/
|
||||||
|
constructor(
|
||||||
|
route: ActivatedRoute,
|
||||||
|
dataProvider: DataProvider,
|
||||||
|
network: Network,
|
||||||
|
favoritesService: FavoritesService,
|
||||||
|
translateService: TranslateService,
|
||||||
|
private hebisDataProvider: HebisDataProvider,
|
||||||
|
) {
|
||||||
|
super(route, dataProvider, network, favoritesService, translateService);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if we have internet
|
||||||
|
*/
|
||||||
|
isDisconnected(): boolean {
|
||||||
|
return this.network.type === this.network.Connection.NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize
|
||||||
|
*/
|
||||||
|
async ionViewWillEnter() {
|
||||||
|
const uid = this.route.snapshot.paramMap.get('uid') || '';
|
||||||
|
await this.getItem(uid ?? '');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides data item with given UID
|
||||||
|
*
|
||||||
|
* @param uid Unique identifier of a thing
|
||||||
|
*/
|
||||||
|
async getItem(uid: SCUuid) {
|
||||||
|
this.hebisDataProvider.hebisSearch({query: uid, page: 0}).then(result => {
|
||||||
|
// eslint-disable-next-line unicorn/no-null
|
||||||
|
this.item = (result.data && result.data[0]) || null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
51
src/app/modules/hebis/hebis-detail/hebis-detail.html
Normal file
51
src/app/modules/hebis/hebis-detail/hebis-detail.html
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
<ion-header>
|
||||||
|
<ion-toolbar>
|
||||||
|
<ion-buttons slot="start">
|
||||||
|
<ion-back-button></ion-back-button>
|
||||||
|
<ion-menu-button></ion-menu-button>
|
||||||
|
</ion-buttons>
|
||||||
|
<ion-title>{{ 'data.detail.TITLE' | translate }}</ion-title>
|
||||||
|
<ion-buttons slot="primary">
|
||||||
|
<stapps-favorite-button
|
||||||
|
*ngIf="item"
|
||||||
|
[item]="item"
|
||||||
|
></stapps-favorite-button>
|
||||||
|
</ion-buttons>
|
||||||
|
</ion-toolbar>
|
||||||
|
</ion-header>
|
||||||
|
<ion-content class="ion-no-padding">
|
||||||
|
<ion-refresher slot="fixed" (ionRefresh)="refresh($event.target)">
|
||||||
|
<ion-refresher-content
|
||||||
|
pullingIcon="chevron-down-outline"
|
||||||
|
pullingText="{{ 'data.REFRESH_ACTION' | translate }}"
|
||||||
|
refreshingText="{{ 'data.REFRESHING' | translate }}"
|
||||||
|
>
|
||||||
|
</ion-refresher-content>
|
||||||
|
</ion-refresher>
|
||||||
|
<div [ngSwitch]="true">
|
||||||
|
<ng-container *ngSwitchCase="!item && isDisconnected()">
|
||||||
|
<div class="notFoundContainer">
|
||||||
|
<ion-icon name="no-connection"> </ion-icon>
|
||||||
|
<ion-label>
|
||||||
|
{{ 'data.detail.COULD_NOT_CONNECT' | translate }}
|
||||||
|
</ion-label>
|
||||||
|
</div>
|
||||||
|
</ng-container>
|
||||||
|
<ng-container *ngSwitchCase="item === null">
|
||||||
|
<div class="notFoundContainer">
|
||||||
|
<ion-icon name="broken-link"> </ion-icon>
|
||||||
|
<ion-label>
|
||||||
|
{{ 'data.detail.NOT_FOUND' | translate }}
|
||||||
|
</ion-label>
|
||||||
|
</div>
|
||||||
|
</ng-container>
|
||||||
|
<ng-container *ngSwitchCase="!item && item !== null">
|
||||||
|
<stapps-skeleton-list-item></stapps-skeleton-list-item>
|
||||||
|
<stapps-skeleton-simple-card></stapps-skeleton-simple-card>
|
||||||
|
</ng-container>
|
||||||
|
<ng-container *ngSwitchDefault>
|
||||||
|
<stapps-hebis-detail-content [item]="item"></stapps-hebis-detail-content>
|
||||||
|
<stapps-daia-availability *ngIf="item"></stapps-daia-availability>
|
||||||
|
</ng-container>
|
||||||
|
</div>
|
||||||
|
</ion-content>
|
||||||
5
src/app/modules/hebis/hebis-detail/hebis-detail.scss
Normal file
5
src/app/modules/hebis/hebis-detail/hebis-detail.scss
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
::ng-deep {
|
||||||
|
ion-card-header {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
32
src/app/modules/hebis/hebis-routing.module.ts
Normal file
32
src/app/modules/hebis/hebis-routing.module.ts
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018-2021 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
import {NgModule} from '@angular/core';
|
||||||
|
import {RouterModule, Routes} from '@angular/router';
|
||||||
|
import {HebisDetailComponent} from './hebis-detail/hebis-detail.component';
|
||||||
|
import {HebisSearchPageComponent} from './list/hebis-search-page.component';
|
||||||
|
|
||||||
|
const hebisRoutes: Routes = [
|
||||||
|
{path: 'hebis-search', component: HebisSearchPageComponent},
|
||||||
|
{path: 'hebis-detail/:uid', component: HebisDetailComponent},
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module defining routes for data module
|
||||||
|
*/
|
||||||
|
@NgModule({
|
||||||
|
exports: [RouterModule],
|
||||||
|
imports: [RouterModule.forChild(hebisRoutes)],
|
||||||
|
})
|
||||||
|
export class HebisRoutingModule {}
|
||||||
100
src/app/modules/hebis/hebis.module.ts
Normal file
100
src/app/modules/hebis/hebis.module.ts
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018-2021 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
import {ScrollingModule} from '@angular/cdk/scrolling';
|
||||||
|
import {CommonModule} from '@angular/common';
|
||||||
|
import {HttpClientModule} from '@angular/common/http';
|
||||||
|
import {NgModule} from '@angular/core';
|
||||||
|
import {FormsModule} from '@angular/forms';
|
||||||
|
import {Network} from '@ionic-native/network/ngx';
|
||||||
|
import {IonicModule} from '@ionic/angular';
|
||||||
|
import {TranslateModule} from '@ngx-translate/core';
|
||||||
|
import {MarkdownModule} from 'ngx-markdown';
|
||||||
|
import {MomentModule} from 'ngx-moment';
|
||||||
|
import {ThingTranslateModule} from '../../translation/thing-translate.module';
|
||||||
|
import {MenuModule} from '../menu/menu.module';
|
||||||
|
import {StorageModule} from '../storage/storage.module';
|
||||||
|
import {HebisDetailComponent} from './hebis-detail/hebis-detail.component';
|
||||||
|
import {HebisDetailContentComponent} from './hebis-detail/hebis-detail-content.component';
|
||||||
|
import {HebisSearchPageComponent} from './list/hebis-search-page.component';
|
||||||
|
import {HebisDataProvider} from './hebis-data.provider';
|
||||||
|
import {DaiaDataProvider} from './daia-data.provider';
|
||||||
|
import {StAppsWebHttpClient} from '../data/stapps-web-http-client.provider';
|
||||||
|
import {HebisRoutingModule} from './hebis-routing.module';
|
||||||
|
import {DataModule} from '../data/data.module';
|
||||||
|
|
||||||
|
import {BookDetailContentComponent} from './types/book/book-detail-content.component';
|
||||||
|
import {BookListItemComponent} from './types/book/book-list-item.component';
|
||||||
|
|
||||||
|
import {PeriodicalListItemComponent} from './types/periodical/periodical-list-item.component';
|
||||||
|
import {PeriodicalDetailContentComponent} from './types/periodical/periodical-detail-content.component';
|
||||||
|
import {HebisArticleListItemComponent} from './types/hebis-article/hebis-article-item.component';
|
||||||
|
import {HebisArticleContentComponent} from './types/hebis-article/hebis-article-content.component';
|
||||||
|
import {DataListComponent} from '../data/list/data-list.component';
|
||||||
|
import {DaiaAvailabilityComponent} from './daia-availability/daia-availability.component';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module for handling data
|
||||||
|
*/
|
||||||
|
@NgModule({
|
||||||
|
declarations: [
|
||||||
|
HebisSearchPageComponent,
|
||||||
|
HebisDetailComponent,
|
||||||
|
HebisDetailContentComponent,
|
||||||
|
DaiaAvailabilityComponent,
|
||||||
|
BookDetailContentComponent,
|
||||||
|
BookListItemComponent,
|
||||||
|
PeriodicalDetailContentComponent,
|
||||||
|
PeriodicalListItemComponent,
|
||||||
|
HebisArticleListItemComponent,
|
||||||
|
HebisArticleContentComponent,
|
||||||
|
],
|
||||||
|
entryComponents: [DataListComponent],
|
||||||
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
DataModule,
|
||||||
|
FormsModule,
|
||||||
|
HebisRoutingModule,
|
||||||
|
HttpClientModule,
|
||||||
|
IonicModule.forRoot(),
|
||||||
|
MarkdownModule.forRoot(),
|
||||||
|
MenuModule,
|
||||||
|
MomentModule.forRoot({
|
||||||
|
relativeTimeThresholdOptions: {
|
||||||
|
m: 59,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
ScrollingModule,
|
||||||
|
StorageModule,
|
||||||
|
TranslateModule.forChild(),
|
||||||
|
ThingTranslateModule.forChild(),
|
||||||
|
],
|
||||||
|
providers: [
|
||||||
|
HebisDataProvider,
|
||||||
|
DaiaDataProvider,
|
||||||
|
Network,
|
||||||
|
StAppsWebHttpClient,
|
||||||
|
],
|
||||||
|
exports: [
|
||||||
|
HebisSearchPageComponent,
|
||||||
|
HebisDetailComponent,
|
||||||
|
HebisDetailContentComponent,
|
||||||
|
DaiaAvailabilityComponent,
|
||||||
|
PeriodicalDetailContentComponent,
|
||||||
|
BookDetailContentComponent,
|
||||||
|
HebisArticleListItemComponent,
|
||||||
|
HebisArticleContentComponent,
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class HebisModule {}
|
||||||
186
src/app/modules/hebis/list/hebis-search-page.component.ts
Normal file
186
src/app/modules/hebis/list/hebis-search-page.component.ts
Normal file
@@ -0,0 +1,186 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018-2021 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
import {Component, Input, OnInit, OnDestroy} from '@angular/core';
|
||||||
|
import {Router} from '@angular/router';
|
||||||
|
import {AlertController} from '@ionic/angular';
|
||||||
|
import {NGXLogger} from 'ngx-logger';
|
||||||
|
import {combineLatest} from 'rxjs';
|
||||||
|
import {debounceTime, distinctUntilChanged, startWith} from 'rxjs/operators';
|
||||||
|
import {ContextMenuService} from '../../menu/context/context-menu.service';
|
||||||
|
import {SettingsProvider} from '../../settings/settings.provider';
|
||||||
|
import {DataRoutingService} from '../../data/data-routing.service';
|
||||||
|
import {SearchPageComponent} from '../../data/list/search-page.component';
|
||||||
|
import {HebisDataProvider} from '../hebis-data.provider';
|
||||||
|
import {PositionService} from '../../map/position.service';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HebisSearchPageComponent queries things and shows list of things as search results and filter as context menu
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: 'stapps-hebissearch-page',
|
||||||
|
templateUrl: 'hebis-search-page.html',
|
||||||
|
})
|
||||||
|
export class HebisSearchPageComponent
|
||||||
|
extends SearchPageComponent
|
||||||
|
implements OnInit, OnDestroy
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* If routing should be done if the user clicks on an item
|
||||||
|
*/
|
||||||
|
@Input() itemRouting? = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Current page to start query
|
||||||
|
*/
|
||||||
|
page = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Injects the providers and creates subscriptions
|
||||||
|
*
|
||||||
|
* @param alertController AlertController
|
||||||
|
* @param dataProvider HebisProvider
|
||||||
|
* @param contextMenuService ContextMenuService
|
||||||
|
* @param settingsProvider SettingsProvider
|
||||||
|
* @param logger An angular logger
|
||||||
|
* @param dataRoutingService DataRoutingService
|
||||||
|
* @param router Router
|
||||||
|
* @param positionService PositionService
|
||||||
|
*/
|
||||||
|
constructor(
|
||||||
|
protected readonly alertController: AlertController,
|
||||||
|
protected dataProvider: HebisDataProvider,
|
||||||
|
protected readonly contextMenuService: ContextMenuService,
|
||||||
|
protected readonly settingsProvider: SettingsProvider,
|
||||||
|
protected readonly logger: NGXLogger,
|
||||||
|
protected dataRoutingService: DataRoutingService,
|
||||||
|
protected router: Router,
|
||||||
|
protected positionService: PositionService,
|
||||||
|
) {
|
||||||
|
super(
|
||||||
|
alertController,
|
||||||
|
dataProvider,
|
||||||
|
contextMenuService,
|
||||||
|
settingsProvider,
|
||||||
|
logger,
|
||||||
|
dataRoutingService,
|
||||||
|
router,
|
||||||
|
positionService,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches items with set query configuration
|
||||||
|
*
|
||||||
|
* @param append If true fetched data gets appended to existing, override otherwise (default false)
|
||||||
|
*/
|
||||||
|
protected async fetchAndUpdateItems(append = false): Promise<void> {
|
||||||
|
// build query search options
|
||||||
|
const searchOptions: {page: number; query: string} = {
|
||||||
|
page: this.page,
|
||||||
|
query: '',
|
||||||
|
};
|
||||||
|
|
||||||
|
if (this.queryText && this.queryText.length > 0) {
|
||||||
|
// add query string
|
||||||
|
searchOptions.query = this.queryText;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.dataProvider.hebisSearch(searchOptions).then(
|
||||||
|
async result => {
|
||||||
|
/*this.singleTypeResponse =
|
||||||
|
result.facets.find(facet => facet.field === 'type')?.buckets
|
||||||
|
.length === 1;*/
|
||||||
|
if (append) {
|
||||||
|
let items = await this.items;
|
||||||
|
// append results
|
||||||
|
items = [...items, ...result.data];
|
||||||
|
this.items = (async () => items)();
|
||||||
|
} else {
|
||||||
|
// override items with results
|
||||||
|
this.items = (async () => {
|
||||||
|
return result.data;
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async error => {
|
||||||
|
const alert: HTMLIonAlertElement = await this.alertController.create({
|
||||||
|
buttons: ['Dismiss'],
|
||||||
|
header: 'Error',
|
||||||
|
subHeader: error.message,
|
||||||
|
});
|
||||||
|
|
||||||
|
await alert.present();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads next page of things
|
||||||
|
*/
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
async loadMore(): Promise<void> {
|
||||||
|
this.page += 1;
|
||||||
|
await this.fetchAndUpdateItems(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
//this.fetchAndUpdateItems();
|
||||||
|
this.initialize();
|
||||||
|
|
||||||
|
this.subscriptions.push(
|
||||||
|
combineLatest([
|
||||||
|
this.queryTextChanged.pipe(
|
||||||
|
debounceTime(this.searchQueryDueTime),
|
||||||
|
distinctUntilChanged(),
|
||||||
|
startWith(this.queryText),
|
||||||
|
),
|
||||||
|
]).subscribe(async query => {
|
||||||
|
this.queryText = query[0];
|
||||||
|
this.page = 0;
|
||||||
|
if (this.queryText?.length > 0 || this.showDefaultData) {
|
||||||
|
await this.fetchAndUpdateItems();
|
||||||
|
this.queryChanged.next();
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
this.settingsProvider.settingsActionChanged$.subscribe(
|
||||||
|
({type, payload}) => {
|
||||||
|
if (type === 'stapps.settings.changed') {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||||
|
const {category, name, value} = payload!;
|
||||||
|
this.logger.log(`received event "settings.changed" with category:
|
||||||
|
${category}, name: ${name}, value: ${JSON.stringify(value)}`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
this.dataRoutingService.itemSelectListener().subscribe(async item => {
|
||||||
|
if (this.itemRouting) {
|
||||||
|
void this.router.navigate([
|
||||||
|
'hebis-detail',
|
||||||
|
(item.origin &&
|
||||||
|
'originalId' in item.origin &&
|
||||||
|
item.origin['originalId']) ||
|
||||||
|
'',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnDestroy() {
|
||||||
|
for (const subscription of this.subscriptions) {
|
||||||
|
subscription.unsubscribe();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
39
src/app/modules/hebis/list/hebis-search-page.html
Normal file
39
src/app/modules/hebis/list/hebis-search-page.html
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
<stapps-context contentId="data-list"></stapps-context>
|
||||||
|
<ion-header>
|
||||||
|
<ion-toolbar>
|
||||||
|
<ion-buttons slot="start">
|
||||||
|
<ion-back-button></ion-back-button>
|
||||||
|
<ion-menu-button></ion-menu-button>
|
||||||
|
</ion-buttons>
|
||||||
|
<ion-buttons slot="end">
|
||||||
|
<ion-menu-button menu="context" auto-hide="false">
|
||||||
|
<ion-icon name="options"></ion-icon>
|
||||||
|
</ion-menu-button>
|
||||||
|
</ion-buttons>
|
||||||
|
<ion-searchbar
|
||||||
|
(ngModelChange)="searchStringChanged($event)"
|
||||||
|
[(ngModel)]="queryText"
|
||||||
|
showClearButton="always"
|
||||||
|
placeholder="{{ 'hebisSearch.search_bar.placeholder' | translate }}"
|
||||||
|
>
|
||||||
|
</ion-searchbar>
|
||||||
|
</ion-toolbar>
|
||||||
|
</ion-header>
|
||||||
|
|
||||||
|
<ion-content>
|
||||||
|
<div
|
||||||
|
[style.display]="!showDefaultData && !items && !loading ? 'block' : 'none'"
|
||||||
|
>
|
||||||
|
<ion-label class="centeredMessageContainer">
|
||||||
|
{{ 'hebisSearch.instruction' | translate }}
|
||||||
|
</ion-label>
|
||||||
|
</div>
|
||||||
|
<stapps-data-list
|
||||||
|
id="data-list"
|
||||||
|
[items]="items | async"
|
||||||
|
[singleType]="singleTypeResponse"
|
||||||
|
(loadmore)="loadMore()"
|
||||||
|
[resetToTop]="queryChanged.asObservable()"
|
||||||
|
[loading]="loading"
|
||||||
|
></stapps-data-list>
|
||||||
|
</ion-content>
|
||||||
20
src/app/modules/hebis/protocol/request.ts
Normal file
20
src/app/modules/hebis/protocol/request.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import {SCLicensePlate} from '@openstapps/core';
|
||||||
|
|
||||||
|
export interface SCHebisSearchRequest {
|
||||||
|
/**
|
||||||
|
* HDS2 will supply results for the speficied insitute / university if available (Defaults to f-u)
|
||||||
|
*/
|
||||||
|
institute?: SCLicensePlate;
|
||||||
|
/**
|
||||||
|
* Simple pagination support (Defaults to 0)
|
||||||
|
*/
|
||||||
|
page?: number;
|
||||||
|
/**
|
||||||
|
* Search query for HDS
|
||||||
|
*/
|
||||||
|
query: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SCDaiaAvailabilityRequest {
|
||||||
|
id: string;
|
||||||
|
}
|
||||||
58
src/app/modules/hebis/protocol/response.ts
Normal file
58
src/app/modules/hebis/protocol/response.ts
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
import {
|
||||||
|
SCArticle,
|
||||||
|
SCBook,
|
||||||
|
SCPeriodical,
|
||||||
|
SCSearchResultPagination,
|
||||||
|
} from '@openstapps/core';
|
||||||
|
|
||||||
|
export interface SCHebisSearchResponse {
|
||||||
|
/**
|
||||||
|
* Response Array of SCBook type or Object
|
||||||
|
*/
|
||||||
|
data: Array<SCBook | SCArticle | SCPeriodical>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pagination information
|
||||||
|
*/
|
||||||
|
pagination: SCSearchResultPagination;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SCDaiaAvailabilityResponse {
|
||||||
|
document: Array<{
|
||||||
|
item: Array<{
|
||||||
|
id: string;
|
||||||
|
label: string;
|
||||||
|
department: SCDaiaSimpleContent;
|
||||||
|
available: SCDaiaService[];
|
||||||
|
unavailable: SCDaiaService[];
|
||||||
|
debugInfo: string;
|
||||||
|
about?: string;
|
||||||
|
storage?: SCDaiaSimpleContent;
|
||||||
|
}>;
|
||||||
|
}>;
|
||||||
|
institution: SCDaiaSimpleContent;
|
||||||
|
timestamp: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SCDaiaSimpleContent {
|
||||||
|
id: string;
|
||||||
|
content: string;
|
||||||
|
href?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SCDaiaService {
|
||||||
|
delay?: string;
|
||||||
|
href?: string;
|
||||||
|
service: string;
|
||||||
|
limitations?: SCDaiaSimpleContent[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SCDaiaHoldings {
|
||||||
|
id: string;
|
||||||
|
label: string;
|
||||||
|
href?: string;
|
||||||
|
signature: string;
|
||||||
|
storage?: SCDaiaSimpleContent;
|
||||||
|
available?: SCDaiaService;
|
||||||
|
about?: string;
|
||||||
|
}
|
||||||
54
src/app/modules/hebis/protocol/route.ts
Normal file
54
src/app/modules/hebis/protocol/route.ts
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
import {
|
||||||
|
SCAbstractRoute,
|
||||||
|
SCRouteHttpVerbs,
|
||||||
|
SCInternalServerErrorResponse,
|
||||||
|
SCMethodNotAllowedErrorResponse,
|
||||||
|
SCRequestBodyTooLargeErrorResponse,
|
||||||
|
SCSyntaxErrorResponse,
|
||||||
|
SCUnsupportedMediaTypeErrorResponse,
|
||||||
|
SCValidationErrorResponse,
|
||||||
|
} from '@openstapps/core';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Route for searching things
|
||||||
|
*/
|
||||||
|
export class SCHebisSearchRoute extends SCAbstractRoute {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.errorNames = [
|
||||||
|
SCInternalServerErrorResponse,
|
||||||
|
SCMethodNotAllowedErrorResponse,
|
||||||
|
SCRequestBodyTooLargeErrorResponse,
|
||||||
|
SCSyntaxErrorResponse,
|
||||||
|
SCUnsupportedMediaTypeErrorResponse,
|
||||||
|
SCValidationErrorResponse,
|
||||||
|
];
|
||||||
|
this.method = SCRouteHttpVerbs.POST;
|
||||||
|
this.requestBodyName = 'SCHebisSearchRequest';
|
||||||
|
this.responseBodyName = 'SCHebisSearchResponse';
|
||||||
|
this.statusCodeSuccess = 200;
|
||||||
|
this.urlPath = '/hebissearch';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Route for availability
|
||||||
|
*/
|
||||||
|
export class SCDaiaRoute extends SCAbstractRoute {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.errorNames = [
|
||||||
|
SCInternalServerErrorResponse,
|
||||||
|
SCMethodNotAllowedErrorResponse,
|
||||||
|
SCRequestBodyTooLargeErrorResponse,
|
||||||
|
SCSyntaxErrorResponse,
|
||||||
|
SCUnsupportedMediaTypeErrorResponse,
|
||||||
|
SCValidationErrorResponse,
|
||||||
|
];
|
||||||
|
this.method = SCRouteHttpVerbs.GET;
|
||||||
|
this.requestBodyName = 'SCDaiaAvailabilityRequest';
|
||||||
|
this.responseBodyName = 'SCDaiaAvailabilityResponse';
|
||||||
|
this.statusCodeSuccess = 200;
|
||||||
|
this.urlPath = '/UB_Frankfurt';
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2019 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
import {Component, Input} from '@angular/core';
|
||||||
|
import {SCBook} from '@openstapps/core';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: 'stapps-book-detail-content',
|
||||||
|
templateUrl: 'book-detail-content.html',
|
||||||
|
})
|
||||||
|
export class BookDetailContentComponent {
|
||||||
|
/**
|
||||||
|
* TODO
|
||||||
|
*/
|
||||||
|
@Input() item: SCBook;
|
||||||
|
}
|
||||||
82
src/app/modules/hebis/types/book/book-detail-content.html
Normal file
82
src/app/modules/hebis/types/book/book-detail-content.html
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
<ion-card *ngIf="item.sameAs">
|
||||||
|
<ion-card-header>{{
|
||||||
|
'hebisSearch.detail.title' | translate
|
||||||
|
}}</ion-card-header>
|
||||||
|
<ion-card-content>
|
||||||
|
<a [href]="item.sameAs" target="_blank">{{
|
||||||
|
'name' | thingTranslate: item | titlecase
|
||||||
|
}}</a>
|
||||||
|
</ion-card-content>
|
||||||
|
</ion-card>
|
||||||
|
|
||||||
|
<stapps-simple-card
|
||||||
|
*ngIf="!item.sameAs"
|
||||||
|
[title]="'name' | propertyNameTranslate: item | titlecase"
|
||||||
|
[content]="'name' | thingTranslate: item"
|
||||||
|
>
|
||||||
|
</stapps-simple-card>
|
||||||
|
|
||||||
|
<stapps-simple-card
|
||||||
|
*ngIf="item.description"
|
||||||
|
[title]="'hebisSearch.detail.description' | translate"
|
||||||
|
[content]="item.description"
|
||||||
|
></stapps-simple-card>
|
||||||
|
|
||||||
|
<stapps-simple-card
|
||||||
|
*ngIf="item.sourceOrganization"
|
||||||
|
[title]="'sourceOrganization' | propertyNameTranslate: item | titlecase"
|
||||||
|
[content]="item.sourceOrganization"
|
||||||
|
></stapps-simple-card>
|
||||||
|
|
||||||
|
<ion-card *ngIf="item.authors && item.authors.length > 0">
|
||||||
|
<ion-card-header>{{
|
||||||
|
'authors' | propertyNameTranslate: item | titlecase
|
||||||
|
}}</ion-card-header>
|
||||||
|
<ion-card-content>
|
||||||
|
<ion-label *ngFor="let author of item.authors">{{
|
||||||
|
'name' | thingTranslate: author
|
||||||
|
}}</ion-label>
|
||||||
|
</ion-card-content>
|
||||||
|
</ion-card>
|
||||||
|
|
||||||
|
<stapps-simple-card
|
||||||
|
*ngIf="item.ISBNs"
|
||||||
|
[title]="'ISBNs' | propertyNameTranslate: item | titlecase"
|
||||||
|
[content]="item.ISBNs"
|
||||||
|
>
|
||||||
|
</stapps-simple-card>
|
||||||
|
<stapps-simple-card
|
||||||
|
*ngIf="item.firstPublished && !item.lastPublished"
|
||||||
|
[title]="'hebisSearch.detail.firstPublished' | translate"
|
||||||
|
[content]="item.firstPublished"
|
||||||
|
>
|
||||||
|
</stapps-simple-card>
|
||||||
|
<stapps-simple-card
|
||||||
|
*ngIf="item.firstPublished && item.lastPublished"
|
||||||
|
[title]="'hebisSearch.detail.firstPublished' | translate"
|
||||||
|
[content]="[item.firstPublished, item.lastPublished] | join: ' - '"
|
||||||
|
>
|
||||||
|
</stapps-simple-card>
|
||||||
|
<ion-card *ngIf="item.publications">
|
||||||
|
<ion-card-header>{{
|
||||||
|
'publications' | propertyNameTranslate: item | titlecase
|
||||||
|
}}</ion-card-header>
|
||||||
|
<ion-card-content>
|
||||||
|
<p *ngFor="let publication of item.publications">
|
||||||
|
{{ publication.locations | join: ', ' }}
|
||||||
|
{{ publication.locations && publication.publisher ? ':' : '' }}
|
||||||
|
{{ publication.publisher }}
|
||||||
|
</p>
|
||||||
|
</ion-card-content>
|
||||||
|
</ion-card>
|
||||||
|
<ion-card *ngIf="item.categories">
|
||||||
|
<ion-card-header>{{
|
||||||
|
'categories' | propertyNameTranslate: item | titlecase
|
||||||
|
}}</ion-card-header>
|
||||||
|
<ion-card-content>
|
||||||
|
<ion-chip [attr.color]="'primary'">
|
||||||
|
<ion-icon [attr.name]="item.type | dataIcon"></ion-icon>
|
||||||
|
<ion-label>{{ 'categories' | thingTranslate: item }}</ion-label>
|
||||||
|
</ion-chip>
|
||||||
|
</ion-card-content>
|
||||||
|
</ion-card>
|
||||||
31
src/app/modules/hebis/types/book/book-list-item.component.ts
Normal file
31
src/app/modules/hebis/types/book/book-list-item.component.ts
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2019 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
import {Component, Input} from '@angular/core';
|
||||||
|
import {SCBook} from '@openstapps/core';
|
||||||
|
import {DataListItemComponent} from '../../../data/list/data-list-item.component';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: 'stapps-book-list-item',
|
||||||
|
templateUrl: 'book-list-item.html',
|
||||||
|
})
|
||||||
|
export class BookListItemComponent extends DataListItemComponent {
|
||||||
|
/**
|
||||||
|
* TODO
|
||||||
|
*/
|
||||||
|
@Input() item: SCBook;
|
||||||
|
}
|
||||||
16
src/app/modules/hebis/types/book/book-list-item.html
Normal file
16
src/app/modules/hebis/types/book/book-list-item.html
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<ion-grid>
|
||||||
|
<ion-row>
|
||||||
|
<ion-col>
|
||||||
|
<h2 class="name">{{ 'name' | thingTranslate: item }}</h2>
|
||||||
|
<p *ngIf="item.keywords">
|
||||||
|
<stapps-long-inline-text
|
||||||
|
[text]="item.keywords.join(', ')"
|
||||||
|
[size]="110"
|
||||||
|
></stapps-long-inline-text>
|
||||||
|
</p>
|
||||||
|
<ion-note>
|
||||||
|
{{ 'type' | thingTranslate: item }}
|
||||||
|
</ion-note>
|
||||||
|
</ion-col>
|
||||||
|
</ion-row>
|
||||||
|
</ion-grid>
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2019 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
import {Component, Input} from '@angular/core';
|
||||||
|
import {SCArticle} from '@openstapps/core';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: 'stapps-hebis-article-content',
|
||||||
|
templateUrl: 'hebis-article-content.html',
|
||||||
|
})
|
||||||
|
export class HebisArticleContentComponent {
|
||||||
|
/**
|
||||||
|
* TODO
|
||||||
|
*/
|
||||||
|
@Input() item: SCArticle;
|
||||||
|
}
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
<ion-card *ngIf="item.sameAs">
|
||||||
|
<ion-card-header>{{
|
||||||
|
'hebisSearch.detail.title' | translate
|
||||||
|
}}</ion-card-header>
|
||||||
|
<ion-card-content>
|
||||||
|
<a [href]="item.sameAs" target="_blank">{{
|
||||||
|
'name' | thingTranslate: item | titlecase
|
||||||
|
}}</a>
|
||||||
|
</ion-card-content>
|
||||||
|
</ion-card>
|
||||||
|
|
||||||
|
<stapps-simple-card
|
||||||
|
*ngIf="!item.sameAs"
|
||||||
|
[title]="'name' | propertyNameTranslate: item | titlecase"
|
||||||
|
[content]="'name' | thingTranslate: item"
|
||||||
|
>
|
||||||
|
</stapps-simple-card>
|
||||||
|
|
||||||
|
<stapps-simple-card
|
||||||
|
*ngIf="item.description"
|
||||||
|
[title]="'hebisSearch.detail.description' | translate"
|
||||||
|
[content]="item.description"
|
||||||
|
></stapps-simple-card>
|
||||||
|
|
||||||
|
<stapps-simple-card
|
||||||
|
*ngIf="item.sourceOrganization"
|
||||||
|
[title]="'sourceOrganization' | propertyNameTranslate: item | titlecase"
|
||||||
|
[content]="item.sourceOrganization"
|
||||||
|
></stapps-simple-card>
|
||||||
|
|
||||||
|
<ion-card *ngIf="item.authors && item.authors.length > 0">
|
||||||
|
<ion-card-header>{{
|
||||||
|
'authors' | propertyNameTranslate: item | titlecase
|
||||||
|
}}</ion-card-header>
|
||||||
|
<ion-card-content>
|
||||||
|
<ion-label *ngFor="let author of item.authors">{{
|
||||||
|
'name' | thingTranslate: author
|
||||||
|
}}</ion-label>
|
||||||
|
</ion-card-content>
|
||||||
|
</ion-card>
|
||||||
|
|
||||||
|
<stapps-simple-card
|
||||||
|
*ngIf="item.firstPublished && !item.lastPublished"
|
||||||
|
[title]="'hebisSearch.detail.firstPublished' | translate"
|
||||||
|
[content]="item.firstPublished"
|
||||||
|
>
|
||||||
|
</stapps-simple-card>
|
||||||
|
<stapps-simple-card
|
||||||
|
*ngIf="item.firstPublished && item.lastPublished"
|
||||||
|
[title]="'hebisSearch.detail.firstPublished' | translate"
|
||||||
|
[content]="[item.firstPublished, item.lastPublished] | join: ' - '"
|
||||||
|
>
|
||||||
|
</stapps-simple-card>
|
||||||
|
<ion-card *ngIf="item.publications">
|
||||||
|
<ion-card-header>{{
|
||||||
|
'publications' | propertyNameTranslate: item | titlecase
|
||||||
|
}}</ion-card-header>
|
||||||
|
<ion-card-content>
|
||||||
|
<p *ngFor="let publication of item.publications">
|
||||||
|
{{ publication.locations | join: ', ' }}
|
||||||
|
{{ publication.locations && publication.publisher ? ':' : '' }}
|
||||||
|
{{ publication.publisher }}
|
||||||
|
</p>
|
||||||
|
</ion-card-content>
|
||||||
|
</ion-card>
|
||||||
|
<ion-card *ngIf="item.categories">
|
||||||
|
<ion-card-header>{{
|
||||||
|
'categories' | propertyNameTranslate: item | titlecase
|
||||||
|
}}</ion-card-header>
|
||||||
|
<ion-card-content>
|
||||||
|
<ion-chip [attr.color]="'primary'">
|
||||||
|
<ion-icon [attr.name]="item.type | dataIcon"></ion-icon>
|
||||||
|
<ion-label>{{ 'categories' | thingTranslate: item }}</ion-label>
|
||||||
|
</ion-chip>
|
||||||
|
</ion-card-content>
|
||||||
|
</ion-card>
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2019 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
import {Component, Input} from '@angular/core';
|
||||||
|
import {SCArticle} from '@openstapps/core';
|
||||||
|
import {DataListItemComponent} from '../../../data/list/data-list-item.component';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: 'stapps-hebis-article-item',
|
||||||
|
templateUrl: 'hebis-article-item.html',
|
||||||
|
})
|
||||||
|
export class HebisArticleListItemComponent extends DataListItemComponent {
|
||||||
|
/**
|
||||||
|
* TODO
|
||||||
|
*/
|
||||||
|
@Input() item: SCArticle;
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
<ion-grid>
|
||||||
|
<ion-row>
|
||||||
|
<ion-col>
|
||||||
|
<h2 class="name">{{ 'name' | thingTranslate: item }}</h2>
|
||||||
|
<p *ngIf="item.keywords">
|
||||||
|
<stapps-long-inline-text
|
||||||
|
[text]="item.keywords.join(', ')"
|
||||||
|
[size]="110"
|
||||||
|
></stapps-long-inline-text>
|
||||||
|
</p>
|
||||||
|
<ion-note>
|
||||||
|
{{ 'type' | thingTranslate: item }}
|
||||||
|
</ion-note>
|
||||||
|
</ion-col>
|
||||||
|
</ion-row>
|
||||||
|
</ion-grid>
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2019 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
import {Component, Input} from '@angular/core';
|
||||||
|
import {SCPeriodical} from '@openstapps/core';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: 'stapps-periodical-detail-content',
|
||||||
|
templateUrl: 'periodical-detail-content.html',
|
||||||
|
})
|
||||||
|
export class PeriodicalDetailContentComponent {
|
||||||
|
/**
|
||||||
|
* TODO
|
||||||
|
*/
|
||||||
|
@Input() item: SCPeriodical;
|
||||||
|
}
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
<ion-card *ngIf="item.sameAs">
|
||||||
|
<ion-card-header>{{
|
||||||
|
'hebisSearch.detail.title' | translate
|
||||||
|
}}</ion-card-header>
|
||||||
|
<ion-card-content>
|
||||||
|
<a [href]="item.sameAs" target="_blank">{{
|
||||||
|
'name' | thingTranslate: item | titlecase
|
||||||
|
}}</a>
|
||||||
|
</ion-card-content>
|
||||||
|
</ion-card>
|
||||||
|
|
||||||
|
<stapps-simple-card
|
||||||
|
*ngIf="!item.sameAs"
|
||||||
|
[title]="'name' | propertyNameTranslate: item | titlecase"
|
||||||
|
[content]="'name' | thingTranslate: item"
|
||||||
|
>
|
||||||
|
</stapps-simple-card>
|
||||||
|
|
||||||
|
<stapps-simple-card
|
||||||
|
*ngIf="item.description"
|
||||||
|
[title]="'hebisSearch.detail.description' | translate"
|
||||||
|
[content]="item.description"
|
||||||
|
></stapps-simple-card>
|
||||||
|
|
||||||
|
<stapps-simple-card
|
||||||
|
*ngIf="item.sourceOrganization"
|
||||||
|
[title]="'sourceOrganization' | propertyNameTranslate: item | titlecase"
|
||||||
|
[content]="item.sourceOrganization"
|
||||||
|
></stapps-simple-card>
|
||||||
|
|
||||||
|
<ion-card *ngIf="item.authors && item.authors.length > 0">
|
||||||
|
<ion-card-header>{{
|
||||||
|
'authors' | propertyNameTranslate: item | titlecase
|
||||||
|
}}</ion-card-header>
|
||||||
|
<ion-card-content>
|
||||||
|
<ion-label *ngFor="let author of item.authors">{{
|
||||||
|
'name' | thingTranslate: author
|
||||||
|
}}</ion-label>
|
||||||
|
</ion-card-content>
|
||||||
|
</ion-card>
|
||||||
|
|
||||||
|
<stapps-simple-card
|
||||||
|
*ngIf="item.firstPublished && !item.lastPublished"
|
||||||
|
[title]="'hebisSearch.detail.firstPublished' | translate"
|
||||||
|
[content]="item.firstPublished"
|
||||||
|
>
|
||||||
|
</stapps-simple-card>
|
||||||
|
<stapps-simple-card
|
||||||
|
*ngIf="item.firstPublished && item.lastPublished"
|
||||||
|
[title]="'hebisSearch.detail.firstPublished' | translate"
|
||||||
|
[content]="[item.firstPublished, item.lastPublished] | join: ' - '"
|
||||||
|
>
|
||||||
|
</stapps-simple-card>
|
||||||
|
<ion-card *ngIf="item.publications">
|
||||||
|
<ion-card-header>{{
|
||||||
|
'publications' | propertyNameTranslate: item | titlecase
|
||||||
|
}}</ion-card-header>
|
||||||
|
<ion-card-content>
|
||||||
|
<p *ngFor="let publication of item.publications">
|
||||||
|
{{ publication.locations | join: ', ' }}
|
||||||
|
{{ publication.locations && publication.publisher ? ':' : '' }}
|
||||||
|
{{ publication.publisher }}
|
||||||
|
</p>
|
||||||
|
</ion-card-content>
|
||||||
|
</ion-card>
|
||||||
|
<ion-card *ngIf="item.categories">
|
||||||
|
<ion-card-header>{{
|
||||||
|
'categories' | propertyNameTranslate: item | titlecase
|
||||||
|
}}</ion-card-header>
|
||||||
|
<ion-card-content>
|
||||||
|
<ion-chip [attr.color]="'primary'">
|
||||||
|
<ion-icon [attr.name]="item.type | dataIcon"></ion-icon>
|
||||||
|
<ion-label>{{ 'categories' | thingTranslate: item }}</ion-label>
|
||||||
|
</ion-chip>
|
||||||
|
</ion-card-content>
|
||||||
|
</ion-card>
|
||||||
|
<stapps-simple-card
|
||||||
|
*ngIf="item.ISSNs"
|
||||||
|
[title]="'hebisSearch.detail.issn' | translate"
|
||||||
|
[content]="item.ISSNs | join: ', '"
|
||||||
|
>
|
||||||
|
</stapps-simple-card>
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2019 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
import {Component, Input} from '@angular/core';
|
||||||
|
import {SCPeriodical} from '@openstapps/core';
|
||||||
|
import {DataListItemComponent} from '../../../data/list/data-list-item.component';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: 'stapps-periodical-list-item',
|
||||||
|
templateUrl: 'periodical-list-item.html',
|
||||||
|
})
|
||||||
|
export class PeriodicalListItemComponent extends DataListItemComponent {
|
||||||
|
/**
|
||||||
|
* TODO
|
||||||
|
*/
|
||||||
|
@Input() item: SCPeriodical;
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
<ion-grid>
|
||||||
|
<ion-row>
|
||||||
|
<ion-col>
|
||||||
|
<h2 class="name">{{ 'name' | thingTranslate: item }}</h2>
|
||||||
|
<p *ngIf="item.keywords">
|
||||||
|
<stapps-long-inline-text
|
||||||
|
[text]="item.keywords.join(', ')"
|
||||||
|
[size]="110"
|
||||||
|
></stapps-long-inline-text>
|
||||||
|
</p>
|
||||||
|
<ion-note>
|
||||||
|
{{ 'type' | thingTranslate: item }}
|
||||||
|
</ion-note>
|
||||||
|
</ion-col>
|
||||||
|
</ion-row>
|
||||||
|
</ion-grid>
|
||||||
@@ -49,6 +49,7 @@ export class NavigationComponent implements OnInit {
|
|||||||
*/
|
*/
|
||||||
public pages = [
|
public pages = [
|
||||||
{title: 'Search', url: '/search', icon: 'search'},
|
{title: 'Search', url: '/search', icon: 'search'},
|
||||||
|
{title: 'Hebis Search', url: '/hebis-search', icon: 'search'},
|
||||||
{title: 'Schedule', url: '/schedule', icon: 'calendar'},
|
{title: 'Schedule', url: '/schedule', icon: 'calendar'},
|
||||||
{title: 'Settings', url: '/settings', icon: 'settings'},
|
{title: 'Settings', url: '/settings', icon: 'settings'},
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -197,6 +197,29 @@
|
|||||||
"instruction": "Starte oben zu tippen, um Veranstaltungen, Veranstaltungstermine, Personen, Orte, Essen und mehr zu finden ...",
|
"instruction": "Starte oben zu tippen, um Veranstaltungen, Veranstaltungstermine, Personen, Orte, Essen und mehr zu finden ...",
|
||||||
"nothing_found": "Keine Ergebnisse"
|
"nothing_found": "Keine Ergebnisse"
|
||||||
},
|
},
|
||||||
|
"hebisSearch": {
|
||||||
|
"search_bar": {
|
||||||
|
"placeholder": "Suche ..."
|
||||||
|
},
|
||||||
|
"instruction": "Starte oben zu tippen, um Bücher, mehrteilige Werke, Zeitschriften, E-Books und mehr zu finden ...",
|
||||||
|
"nothing_found": "Keine Ergebnisse",
|
||||||
|
"detail": {
|
||||||
|
"title": "Titel",
|
||||||
|
"description": "Umfang",
|
||||||
|
"firstPublished": "Erscheinungsjahr"
|
||||||
|
},
|
||||||
|
"daia": {
|
||||||
|
"availability": "Verfügbarkeit",
|
||||||
|
"available": "ausleihbar",
|
||||||
|
"status": "Status",
|
||||||
|
"location": "Standort",
|
||||||
|
"signature": "Signatur",
|
||||||
|
"comment": "Kommentar",
|
||||||
|
"order": "Bestellen",
|
||||||
|
"issn": "ISSN",
|
||||||
|
"ejournal": "ejournal"
|
||||||
|
}
|
||||||
|
},
|
||||||
"schedule": {
|
"schedule": {
|
||||||
"recurring": "Stundenplan",
|
"recurring": "Stundenplan",
|
||||||
"calendar": "Kalender",
|
"calendar": "Kalender",
|
||||||
|
|||||||
@@ -197,6 +197,29 @@
|
|||||||
"instruction": "Start typing above to find events, persons, places, food and more ...",
|
"instruction": "Start typing above to find events, persons, places, food and more ...",
|
||||||
"nothing_found": "No results"
|
"nothing_found": "No results"
|
||||||
},
|
},
|
||||||
|
"hebisSearch": {
|
||||||
|
"search_bar": {
|
||||||
|
"placeholder": "Search ..."
|
||||||
|
},
|
||||||
|
"instruction": "Start typing above to find books, journals, multipart items, e-books and more ...",
|
||||||
|
"nothing_found": "No results",
|
||||||
|
"detail": {
|
||||||
|
"title": "Title",
|
||||||
|
"description": "Scope",
|
||||||
|
"firstPublished": "Year of publication"
|
||||||
|
},
|
||||||
|
"daia": {
|
||||||
|
"availability": "Availability",
|
||||||
|
"available": "available",
|
||||||
|
"status": "Status",
|
||||||
|
"location": "Location",
|
||||||
|
"signature": "Shelfmark",
|
||||||
|
"comment": "Remark",
|
||||||
|
"order": "Request",
|
||||||
|
"issn": "ISSN",
|
||||||
|
"ejournal": "ejournal"
|
||||||
|
}
|
||||||
|
},
|
||||||
"schedule": {
|
"schedule": {
|
||||||
"recurring": "Recurring",
|
"recurring": "Recurring",
|
||||||
"calendar": "Calendar",
|
"calendar": "Calendar",
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ const appDomain = 'mobile.app.uni-frankfurt.de';
|
|||||||
|
|
||||||
export const environment = {
|
export const environment = {
|
||||||
backend_url: 'https://mobile.server.uni-frankfurt.de',
|
backend_url: 'https://mobile.server.uni-frankfurt.de',
|
||||||
|
daia_url: 'https://daia.hebis.de/DAIA2/UB_Frankfurt',
|
||||||
appDomain: 'mobile.app.uni-frankfurt.de',
|
appDomain: 'mobile.app.uni-frankfurt.de',
|
||||||
backend_version: '2.0.0',
|
backend_version: '2.0.0',
|
||||||
use_fake_backend: false,
|
use_fake_backend: false,
|
||||||
|
|||||||
Reference in New Issue
Block a user