mirror of
https://gitlab.com/openstapps/openstapps.git
synced 2026-01-21 00:52:55 +00:00
@@ -16,10 +16,11 @@ import {CommonModule} from '@angular/common';
|
||||
import {HttpClientModule} from '@angular/common/http';
|
||||
import {NgModule} from '@angular/core';
|
||||
import {FormsModule} from '@angular/forms';
|
||||
import {IonicModule} from '@ionic/angular';
|
||||
import {Events, IonicModule} from '@ionic/angular';
|
||||
import {TranslateModule} from '@ngx-translate/core';
|
||||
import {MarkdownModule} from 'ngx-markdown';
|
||||
import {MomentModule} from 'ngx-moment';
|
||||
import {MenuModule} from '../menu/menu.module';
|
||||
import {StorageModule} from '../storage/storage.module';
|
||||
import {DataFacetsProvider} from './data-facets.provider';
|
||||
import {DataRoutingModule} from './data-routing.module';
|
||||
@@ -116,6 +117,7 @@ import {VideoListItem} from './types/video/video-list-item.component';
|
||||
DataRoutingModule,
|
||||
HttpClientModule,
|
||||
MarkdownModule.forRoot(),
|
||||
MenuModule,
|
||||
MomentModule.forRoot({
|
||||
relativeTimeThresholdOptions: {
|
||||
'm': 59,
|
||||
@@ -127,6 +129,7 @@ import {VideoListItem} from './types/video/video-list-item.component';
|
||||
providers: [
|
||||
DataProvider,
|
||||
DataFacetsProvider,
|
||||
Events,
|
||||
StAppsWebHttpClient,
|
||||
],
|
||||
})
|
||||
|
||||
@@ -12,92 +12,157 @@
|
||||
* 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 {AlertController} from '@ionic/angular';
|
||||
import {SCThing} from '@openstapps/core';
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {AlertController, Events} from '@ionic/angular';
|
||||
import {
|
||||
SCFacet,
|
||||
SCSearchFilter,
|
||||
SCSearchQuery,
|
||||
SCSearchSort,
|
||||
SCSettingValue,
|
||||
SCSettingValues,
|
||||
SCThing,
|
||||
} from '@openstapps/core';
|
||||
import {Logger} from '@openstapps/logger';
|
||||
import {Subject} from 'rxjs';
|
||||
import {debounceTime, distinctUntilChanged} from 'rxjs/operators';
|
||||
import {MenuService} from '../../menu/menu.service';
|
||||
import {DataProvider} from '../data.provider';
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* DataListComponent queries things and shows list of things and context menu
|
||||
*/
|
||||
@Component({
|
||||
selector: 'stapps-data-list',
|
||||
templateUrl: 'data-list.html',
|
||||
})
|
||||
export class DataListComponent {
|
||||
export class DataListComponent implements OnInit {
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* Api query filter
|
||||
*/
|
||||
dataProvider: DataProvider;
|
||||
filterQuery: SCSearchFilter | undefined;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* Thing counter to start query the next page from
|
||||
*/
|
||||
from = 0;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* Container for queried things
|
||||
*/
|
||||
items: SCThing[];
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* Page size of queries
|
||||
*/
|
||||
loaded = false;
|
||||
pageSize = 30;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* Search value from search bar
|
||||
*/
|
||||
query: string;
|
||||
/**
|
||||
* TODO
|
||||
*/
|
||||
queryChanged: Subject<string> = new Subject<string>();
|
||||
queryText: string;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* Subject to handle search text changes
|
||||
*/
|
||||
selectedItem: any;
|
||||
/**
|
||||
* TODO
|
||||
*/
|
||||
size = 30;
|
||||
queryTextChanged: Subject<string> = new Subject<string>();
|
||||
|
||||
/**
|
||||
*
|
||||
* @param alertController TODO
|
||||
* @param dataProvider TODO
|
||||
* Time to wait for search query if search text is changing
|
||||
*/
|
||||
searchQueryDueTime = 1000;
|
||||
|
||||
/**
|
||||
* Api query sorting
|
||||
*/
|
||||
sortQuery: SCSearchSort | undefined;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param alertController AlertController
|
||||
* @param dataProvider DataProvider
|
||||
* @param events Events
|
||||
* @param menuService MenuService
|
||||
*/
|
||||
constructor(
|
||||
private readonly alertController: AlertController,
|
||||
dataProvider: DataProvider,
|
||||
) {
|
||||
this.dataProvider = dataProvider;
|
||||
this.queryChanged
|
||||
private dataProvider: DataProvider,
|
||||
private readonly events: Events,
|
||||
private readonly menuService: MenuService,
|
||||
) {
|
||||
this.queryTextChanged
|
||||
.pipe(
|
||||
debounceTime(1000),
|
||||
debounceTime(this.searchQueryDueTime),
|
||||
distinctUntilChanged())
|
||||
.subscribe((model) => {
|
||||
this.from = 0;
|
||||
this.query = model;
|
||||
this.fetchItems();
|
||||
this.queryText = model;
|
||||
this.fetchAndUpdateItems();
|
||||
});
|
||||
this.fetchItems();
|
||||
|
||||
this.menuService.filterQueryChanged$.subscribe((query) => {
|
||||
this.filterQuery = query;
|
||||
this.fetchAndUpdateItems();
|
||||
});
|
||||
this.menuService.sortQueryChanged$.subscribe((query) => {
|
||||
this.sortQuery = query;
|
||||
this.fetchAndUpdateItems();
|
||||
});
|
||||
|
||||
this.fetchAndUpdateItems();
|
||||
|
||||
/**
|
||||
* Subscribe to 'settings.changed' events
|
||||
*/
|
||||
this.events.subscribe('stapps.settings.changed',
|
||||
(category: string, name: string, value: SCSettingValue | SCSettingValues) => {
|
||||
Logger.log(`received event "settings.changed" with category:
|
||||
${category}, name: ${name}, value: ${JSON.stringify(value)}`);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* Fetches items with set query configuration
|
||||
*
|
||||
* @param append If true fetched data gets appended to existing, override otherwise (default false)
|
||||
*/
|
||||
private async fetchItems(): Promise<any> {
|
||||
return this.dataProvider.search({
|
||||
private async fetchAndUpdateItems(append = false): Promise<void> {
|
||||
// build query search options
|
||||
const searchOptions: SCSearchQuery = {
|
||||
from: this.from,
|
||||
query: this.query,
|
||||
size: this.size,
|
||||
} as any)
|
||||
size: this.pageSize,
|
||||
};
|
||||
|
||||
if (this.queryText && this.queryText.length > 0) {
|
||||
// add query string
|
||||
searchOptions.query = this.queryText;
|
||||
}
|
||||
|
||||
if (this.filterQuery) {
|
||||
// add query filtering
|
||||
searchOptions.filter = this.filterQuery;
|
||||
}
|
||||
|
||||
if (this.sortQuery) {
|
||||
// add query sorting
|
||||
searchOptions.sort = [this.sortQuery];
|
||||
}
|
||||
|
||||
return this.dataProvider.search(searchOptions)
|
||||
.then((result) => {
|
||||
if (append) {
|
||||
// append results
|
||||
this.items = this.items.concat(result.data);
|
||||
} else {
|
||||
// override items with results
|
||||
this.items = result.data;
|
||||
this.loaded = true;
|
||||
}
|
||||
// update filter options if result contains facets
|
||||
if (typeof result.facets !== 'undefined') {
|
||||
this.updateContextFilter(result.facets);
|
||||
}
|
||||
}, async (err) => {
|
||||
const alert: HTMLIonAlertElement = await this.alertController.create({
|
||||
buttons: ['Dismiss'],
|
||||
@@ -110,18 +175,52 @@ export class DataListComponent {
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* Loads next page of things
|
||||
*/
|
||||
// tslint:disable-next-line:no-any
|
||||
async loadMore(event: any): Promise<void> {
|
||||
this.from += this.size;
|
||||
await this.fetchItems();
|
||||
this.from += this.pageSize;
|
||||
await this.fetchAndUpdateItems(true);
|
||||
event.target.complete();
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* Initialises the sort context of menuService
|
||||
*/
|
||||
search(query: string) {
|
||||
this.queryChanged.next(query);
|
||||
ngOnInit(): void {
|
||||
// initialise sort option for context menu
|
||||
this.menuService.setContextSort({
|
||||
name: 'sort',
|
||||
reversed: false,
|
||||
value: 'relevance',
|
||||
values: [
|
||||
{
|
||||
reversible: false,
|
||||
value: 'relevance',
|
||||
},
|
||||
{
|
||||
reversible: true,
|
||||
value: 'name',
|
||||
},
|
||||
{
|
||||
reversible: true,
|
||||
value: 'type',
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Search event of search bar
|
||||
*/
|
||||
searchStringChanged(queryValue: string) {
|
||||
this.queryTextChanged.next(queryValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates context filter in menuService with facets
|
||||
*/
|
||||
updateContextFilter(facets: SCFacet[]) {
|
||||
this.menuService.updateContextFilter(facets);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
<stapps-context></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">
|
||||
<ion-icon name="options"></ion-icon>
|
||||
</ion-menu-button>
|
||||
</ion-buttons>
|
||||
|
||||
<ion-searchbar (ngModelChange)="search($event)" [(ngModel)]="query"></ion-searchbar>
|
||||
<ion-searchbar (ngModelChange)="searchStringChanged($event)" [(ngModel)]="queryText"></ion-searchbar>
|
||||
|
||||
<!--<ion-title>List</ion-title>-->
|
||||
</ion-toolbar>
|
||||
|
||||
Reference in New Issue
Block a user