feat: add HeBIS HDS search

This commit is contained in:
Andy Bastian
2022-01-27 14:11:35 +00:00
committed by Jovan Krunić
parent e4165901bb
commit 9a3241c42a
42 changed files with 2109 additions and 23 deletions

View 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();
}
}
}

View 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>