From 911492d064ff0280dd6626244cd8038cbfc0f408 Mon Sep 17 00:00:00 2001 From: Michel Jonathan Schmitz Date: Wed, 10 Jul 2019 12:38:29 +0200 Subject: [PATCH] fix: update core and apply stricter tslint rules --- .../_helpers/data/resources/test-resources.ts | 14 ++ src/app/_helpers/data/sample-things.ts | 73 ++++--- src/app/_helpers/fake-backend.interceptor.ts | 53 +++-- src/app/app-routing.module.ts | 9 +- src/app/app.component.ts | 103 ++++++---- src/app/app.module.ts | 14 +- src/app/modules/config/config.module.ts | 3 + .../modules/config/config.provider.spec.ts | 8 +- src/app/modules/config/config.provider.ts | 36 ++-- src/app/modules/data/data-facets.provider.ts | 120 +++++++----- src/app/modules/data/data-routing.module.ts | 3 + src/app/modules/data/data.module.ts | 11 +- src/app/modules/data/data.provider.ts | 121 +++++++----- .../detail/data-detail-content.component.ts | 6 + .../data/detail/data-detail.component.ts | 29 ++- .../data/elements/address-detail.component.ts | 6 + .../elements/long-inline-text.component.ts | 11 +- .../data/elements/offers-detail.component.ts | 9 + .../data/elements/offers-in-list.component.ts | 6 + .../data/elements/origin-detail.component.ts | 6 + .../data/elements/origin-in-list.component.ts | 6 + .../data/elements/simple-card.component.ts | 27 ++- .../elements/skeleton-list-item.component.ts | 3 + .../skeleton-simple-card.component.ts | 3 + .../data/list/data-list-item.component.ts | 13 ++ .../modules/data/list/data-list.component.ts | 76 ++++++-- .../data/stapps-web-http-client.provider.ts | 24 ++- .../article-detail-content.component.ts | 20 +- .../article/article-list-item.component.ts | 10 + .../catalog-detail-content.component.ts | 20 +- .../catalog/catalog-list-item.component.ts | 10 + .../date-series-detail-content.component.ts | 20 +- .../date-series-list-item.component.ts | 10 + .../dish/dish-detail-content.component.ts | 20 +- .../types/dish/dish-list-item.component.ts | 12 +- .../event/event-detail-content.component.ts | 20 +- .../types/event/event-list-item.component.ts | 10 + .../favorite-detail-content.component.ts | 20 +- .../favorite/favorite-list-item.component.ts | 10 + .../message-detail-content.component.ts | 20 +- .../types/message/message-detail-content.html | 2 +- .../message/message-list-item.component.ts | 10 + .../data/types/message/message-list-item.html | 4 +- .../organization-detail-content.component.ts | 21 +- .../organization-list-item.component.ts | 10 + .../person/person-detail-content.component.ts | 21 +- .../person/person-list-item.component.ts | 10 + .../place/place-detail-content.component.ts | 21 +- .../types/place/place-list-item.component.ts | 10 + .../semester-detail-content.component.ts | 21 +- .../semester/semester-list-item.component.ts | 11 +- .../video/video-detail-content.component.ts | 21 +- .../types/video/video-list-item.component.ts | 11 +- src/app/modules/menu/menu.module.ts | 13 +- .../menu/navigation/navigation.component.ts | 9 +- .../settings/item/settings-item.component.ts | 65 +++++-- .../modules/settings/item/settings-item.html | 18 +- .../settings/page/settings-page.component.ts | 58 ++++-- .../modules/settings/page/settings-page.html | 2 +- src/app/modules/settings/settings.module.ts | 3 + .../settings/settings.provider.spec.ts | 66 +++---- src/app/modules/settings/settings.provider.ts | 141 +++++++++----- src/app/modules/storage/storage.module.ts | 17 +- src/app/modules/storage/storage.provider.ts | 184 +++++++++--------- src/main.ts | 17 +- src/polyfills.ts | 18 +- src/test.ts | 19 +- 67 files changed, 1291 insertions(+), 507 deletions(-) diff --git a/src/app/_helpers/data/resources/test-resources.ts b/src/app/_helpers/data/resources/test-resources.ts index 9b649a4b..66b1e8a7 100644 --- a/src/app/_helpers/data/resources/test-resources.ts +++ b/src/app/_helpers/data/resources/test-resources.ts @@ -1,3 +1,17 @@ +/* + * 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 . + */ /* tslint:disable */ export const sampleResources = [{ 'errorNames': [], diff --git a/src/app/_helpers/data/sample-things.ts b/src/app/_helpers/data/sample-things.ts index d452b610..26894780 100644 --- a/src/app/_helpers/data/sample-things.ts +++ b/src/app/_helpers/data/sample-things.ts @@ -20,10 +20,11 @@ import {SCAcademicEvent, SCArticle, SCBook, SCBuilding, SCCatalog, import {Observable, of} from 'rxjs'; import {sampleResources} from './resources/test-resources'; +// tslint:disable:no-magic-numbers const sampleMessages: SCMessage[] = [ { audiences: ['students'], - message: 'Foo Message Text', + messageBody: 'Foo Message Text', name: 'Foo Message', origin: { indexed: 'SOME-DATE', @@ -35,7 +36,7 @@ const sampleMessages: SCMessage[] = [ }, { audiences: ['employees'], - message: 'Bar Message Text', + messageBody: 'Bar Message Text', name: 'Bar Message', origin: { indexed: 'SOME-DATE', @@ -363,31 +364,46 @@ export const sampleThingsMap: {[key in SCThingType | string]: SCThing[]} = { tour: [], video: [], }; +// tslint:enable:no-magic-numbers -// provides all or certain sample things to be used in tests or backendless development +/** + * TODO + * + * provides all or certain sample things to be used in tests or backendless development + */ export function getSampleThings(...uids: string[]): SCThing[] { const sampleThings: SCThing[] = []; if (typeof uids !== 'undefined' && uids.length > 0) { uids.forEach((uid) => { - Object.keys(sampleThingsMap).forEach((key) => { - sampleThingsMap[key].forEach((thing) => { - if (thing.uid === uid) { - sampleThings.push(thing); - } + Object.keys(sampleThingsMap) + .forEach((key) => { + sampleThingsMap[key].forEach((thing) => { + if (thing.uid === uid) { + sampleThings.push(thing); + } + }); }); - }); }); } else { - Object.keys(sampleThingsMap).forEach((key) => { - sampleThings.push(...sampleThingsMap[key]); - }); + Object.keys(sampleThingsMap) + .forEach((key) => { + sampleThings.push(...sampleThingsMap[key]); + }); } + return sampleThings; } +/** + * TODO + */ @Injectable() export class SampleThings { + /** + * TODO + */ http: HttpClient; + constructor(http: HttpClient) { this.http = http; } @@ -396,6 +412,28 @@ export class SampleThings { // // return of(sampleDishes[0]); // } + /** + * TODO + */ + // tslint:disable-next-line:prefer-function-over-method + getSampleThing(uid: string): Observable { + // const jsonContent: any[] = await this.http.get('http://localhost:8100/assets/json/joined.json').toPromise(); + const sampleThings: any[] = []; + for (const resource of sampleResources) { + if (resource.instance.uid as SCThingType === uid) { + sampleThings.push(resource.instance); + + return of(sampleThings); + } + } + + return of(sampleThings); + } + + /** + * TODO + */ + // tslint:disable-next-line:prefer-function-over-method getSampleThings(): Observable { // const jsonContent: any[] = await this.http.get('http://localhost:8100/assets/json/joined.json').toPromise(); const sampleThings: any[] = []; @@ -405,18 +443,7 @@ export class SampleThings { sampleThings.push(resource.instance); // } }); - return of(sampleThings); - } - getSampleThing(uid: string): Observable { - // const jsonContent: any[] = await this.http.get('http://localhost:8100/assets/json/joined.json').toPromise(); - const sampleThings: any[] = []; - for (const resource of sampleResources) { - if (resource.instance.uid as SCThingType === uid) { - sampleThings.push(resource.instance); - return of(sampleThings); - } - } return of(sampleThings); } } diff --git a/src/app/_helpers/fake-backend.interceptor.ts b/src/app/_helpers/fake-backend.interceptor.ts index 5feee4b7..9c6059d6 100644 --- a/src/app/_helpers/fake-backend.interceptor.ts +++ b/src/app/_helpers/fake-backend.interceptor.ts @@ -15,11 +15,12 @@ import {HTTP_INTERCEPTORS, HttpClient, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse} from '@angular/common/http'; import {Injectable} from '@angular/core'; -import {SCIndexResponse, SCThingOriginType, SCThingType} from '@openstapps/core'; +import {SCIndexResponse, SCSettingInputType, SCThingOriginType, SCThingType} from '@openstapps/core'; import {Observable, of} from 'rxjs'; -import {map, delay} from 'rxjs/operators'; +import {delay, map} from 'rxjs/operators'; import {SampleThings} from './data/sample-things'; +// tslint:disable:no-magic-numbers const sampleIndexResponse: SCIndexResponse = { app: { campusPolygon: { @@ -58,12 +59,9 @@ const sampleIndexResponse: SCIndexResponse = { settings: [ { categories: ['profile'], + defaultValue: 'student', description: '', - input: { - defaultValue: 'student', - inputType: 'singleChoice', - values: ['student', 'employee', 'guest'], - }, + inputType: SCSettingInputType.SingleChoice, name: 'group', order: 1, origin: { @@ -87,15 +85,13 @@ const sampleIndexResponse: SCIndexResponse = { }, type: SCThingType.Setting, uid: '', + values: ['student', 'employee', 'guest'], }, { categories: ['profile'], + defaultValue: 'en', description: '', - input: { - defaultValue: 'en', - inputType: 'singleChoice', - values: ['en', 'de'], - }, + inputType: SCSettingInputType.SingleChoice, name: 'language', order: 0, origin: { @@ -117,15 +113,13 @@ const sampleIndexResponse: SCIndexResponse = { }, type: SCThingType.Setting, uid: '', + values: ['en', 'de'], }, { categories: ['privacy'], + defaultValue: false, description: '', - input: { - defaultValue: false, - inputType: 'singleChoice', - values: [true, false], - }, + inputType: SCSettingInputType.SingleChoice, name: 'geoLocation', order: 0, origin: { @@ -149,6 +143,7 @@ const sampleIndexResponse: SCIndexResponse = { }, type: SCThingType.Setting, uid: '', + values: [true, false], }, ], }, @@ -226,20 +221,33 @@ const sampleIndexResponse: SCIndexResponse = { }, }; +// tslint:enable:no-magic-numbers + +/** + * TODO + */ @Injectable() export class FakeBackendInterceptor implements HttpInterceptor { + /** + * TODO + */ sampleFetcher: SampleThings; + constructor(http: HttpClient) { this.sampleFetcher = new SampleThings(http); } + /** + * TODO + */ intercept(request: HttpRequest, next: HttpHandler): Observable> { if (request.method === 'POST') { if (request.url.endsWith('/') && request.method === 'POST') { // respond with expected (faked) index response return of(new HttpResponse({status: 200, body: sampleIndexResponse})); // respond with a search response with sample data - } else if (request.url.endsWith('/search')) { + } + if (request.url.endsWith('/search')) { if (typeof request.body.filter !== 'undefined' && typeof request.body.filter.arguments !== 'undefined') { if (request.body.filter.arguments.field === 'uid') { return this.sampleFetcher.getSampleThing(request.body.filter.arguments.value) @@ -248,11 +256,14 @@ export class FakeBackendInterceptor implements HttpInterceptor { }), delay(1000)); // add delay for skeleton screens to be seen (see !16) } } - return this.sampleFetcher.getSampleThings().pipe(map((sampleData: any) => { - return new HttpResponse({status: 200, body: {data: sampleData}}); - }), delay(1000)); // add delay for skeleton screens to be seen (see !16) + + return this.sampleFetcher.getSampleThings() + .pipe(map((sampleData: any) => { + return new HttpResponse({status: 200, body: {data: sampleData}}); + }), delay(1000)); // add delay for skeleton screens to be seen (see !16) } } + return next.handle(request); } } diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index d68c71f8..87e5343c 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 StApps + * 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. @@ -16,11 +16,14 @@ import {NgModule} from '@angular/core'; import {RouterModule, Routes} from '@angular/router'; const routes: Routes = [ - {path: '', redirectTo: '/search', pathMatch: 'full'} + {path: '', redirectTo: '/search', pathMatch: 'full'}, ]; +/** + * TODO + */ @NgModule({ exports: [RouterModule], - imports: [RouterModule.forRoot(routes)] + imports: [RouterModule.forRoot(routes)], }) export class AppRoutingModule {} diff --git a/src/app/app.component.ts b/src/app/app.component.ts index bd9e5b5c..814aa01e 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -21,62 +21,87 @@ import {Logger} from '@openstapps/logger'; import {ConfigProvider} from './modules/config/config.provider'; import {SettingsProvider} from './modules/settings/settings.provider'; -const logger: Logger = new Logger(); - +/** + * TODO + */ @Component({ selector: 'app-root', templateUrl: 'app.component.html', }) export class AppComponent { - logger: Logger = new Logger(); - pages: Array<{ component: any, title: string }>; + /** + * TODO + */ + pages: Array<{ + /** + * TODO + */ + component: any; + /** + * TODO + */ + title: string; + }>; - constructor(private platform: Platform, - private statusBar: StatusBar, - private splashScreen: SplashScreen, - private translateService: TranslateService, - private settingsProvider: SettingsProvider, - private configProvider: ConfigProvider) { + /** + * + * @param platform TODO + * @param statusBar TODO + * @param splashScreen TODO + * @param translateService TODO + * @param settingsProvider TODO + * @param configProvider TODO + */ + constructor(private readonly platform: Platform, + private readonly statusBar: StatusBar, + private readonly splashScreen: SplashScreen, + private readonly translateService: TranslateService, + private readonly settingsProvider: SettingsProvider, + private readonly configProvider: ConfigProvider) { this.initializeApp(); // this language will be used as a fallback when a translation isn't found in the current language translateService.setDefaultLang('en'); } + /** + * TODO + */ initializeApp() { - this.platform.ready().then(async () => { - // Okay, so the platform is ready and our plugins are available. - // Here you can do any higher level native things you might need. - this.statusBar.styleDefault(); - this.splashScreen.hide(); + this.platform.ready() + .then(async () => { + // Okay, so the platform is ready and our plugins are available. + // Here you can do any higher level native things you might need. + this.statusBar.styleDefault(); + this.splashScreen.hide(); - // initialise the configProvider - try { - await this.configProvider.init(); - } catch (error) { - if (typeof error.name !== 'undefined') { - if (error.name === 'ConfigInitError') { - // @TODO: Issue #43 handle initialisation error and inform user + // initialise the configProvider + try { + await this.configProvider.init(); + } catch (error) { + if (typeof error.name !== 'undefined') { + if (error.name === 'ConfigInitError') { + // @TODO: Issue #43 handle initialisation error and inform user + } } + await Logger.error(error); } - logger.error(error); - } - // set order of categories in settings - this.settingsProvider.setCategoriesOrder([ - 'profile', - 'privacy', - 'credentials', - 'others', - ]); + // set order of categories in settings + this.settingsProvider.setCategoriesOrder([ + 'profile', + 'privacy', + 'credentials', + 'others', + ]); - try { - // set language from settings - const languageCode = await this.settingsProvider.getValue('profile', 'language'); - this.translateService.use(languageCode); - } catch (error) { - this.logger.warn(error); - } - }); + try { + // set language from settings + const languageCode = await this.settingsProvider.getValue('profile', 'language'); + this.translateService.use(languageCode); + } catch (error) { + Logger.warn(error); + } + }); } } diff --git a/src/app/app.module.ts b/src/app/app.module.ts index bf0e6a99..5a0b2cf9 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -12,7 +12,7 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ -import {CommonModule, registerLocaleData, LocationStrategy, HashLocationStrategy} from '@angular/common'; +import {CommonModule, HashLocationStrategy, LocationStrategy, registerLocaleData} from '@angular/common'; import {HttpClient} from '@angular/common/http'; import localeDe from '@angular/common/locales/de'; import {NgModule} from '@angular/core'; @@ -34,10 +34,18 @@ import {StorageModule} from './modules/storage/storage.module'; registerLocaleData(localeDe); +/** + * TODO + * + * @param http TODO + */ export function createTranslateLoader(http: HttpClient) { return new TranslateHttpLoader(http, './assets/i18n/', '.json'); } +/** + * TODO + */ @NgModule({ bootstrap: [AppComponent], declarations: [AppComponent], @@ -66,11 +74,11 @@ export function createTranslateLoader(http: HttpClient) { SplashScreen, { provide: RouteReuseStrategy, - useClass: IonicRouteStrategy + useClass: IonicRouteStrategy, }, { provide: LocationStrategy, - useClass: HashLocationStrategy + useClass: HashLocationStrategy, }, ], }) diff --git a/src/app/modules/config/config.module.ts b/src/app/modules/config/config.module.ts index 5b72082b..6b2b34e1 100644 --- a/src/app/modules/config/config.module.ts +++ b/src/app/modules/config/config.module.ts @@ -17,6 +17,9 @@ import {DataModule} from '../data/data.module'; import {StorageModule} from '../storage/storage.module'; import {ConfigProvider} from './config.provider'; +/** + * TODO + */ @NgModule({ imports: [ StorageModule, diff --git a/src/app/modules/config/config.provider.spec.ts b/src/app/modules/config/config.provider.spec.ts index 02b6ec52..76ad910f 100644 --- a/src/app/modules/config/config.provider.spec.ts +++ b/src/app/modules/config/config.provider.spec.ts @@ -13,7 +13,7 @@ * this program. If not, see . */ import {TestBed} from '@angular/core/testing'; -import {SCIndexResponse, SCThingOriginType, SCThingType} from '@openstapps/core'; +import {SCIndexResponse, SCThingOriginType, SCThingType, SCSettingInputType} from '@openstapps/core'; import {StAppsWebHttpClient} from '../data/stapps-web-http-client.provider'; import {StorageProvider} from '../storage/storage.provider'; import {ConfigProvider, STORAGE_KEY_CONFIG} from './config.provider'; @@ -207,10 +207,8 @@ const sampleIndexResponse: SCIndexResponse = { settings: [ { categories: ['credentials'], - input: { - defaultValue: '', - inputType: 'text', - }, + defaultValue: '', + inputType: SCSettingInputType.Text, name: 'username', order: 0, origin: { diff --git a/src/app/modules/config/config.provider.ts b/src/app/modules/config/config.provider.ts index b30a9601..46a2f6a6 100644 --- a/src/app/modules/config/config.provider.ts +++ b/src/app/modules/config/config.provider.ts @@ -39,12 +39,25 @@ export const STORAGE_KEY_CONFIG = 'stapps.config'; */ @Injectable() export class ConfigProvider { + /** + * TODO + */ client: Client; + /** + * TODO + */ config: SCIndexResponse; - initialised: boolean = false; - logger: Logger = new Logger(); + /** + * TODO + */ + initialised = false; - constructor(private storageProvider: StorageProvider, swHttpClient: StAppsWebHttpClient) { + /** + * + * @param storageProvider TODO + * @param swHttpClient TODO + */ + constructor(private readonly storageProvider: StorageProvider, swHttpClient: StAppsWebHttpClient) { this.client = new Client(swHttpClient, environment.backend_url, environment.backend_version); } @@ -77,9 +90,8 @@ export class ConfigProvider { } if (typeof this.config.app[attribute] !== 'undefined') { return this.config.app[attribute]; - } else { - throw new ConfigValueNotAvailable(attribute); } + throw new ConfigValueNotAvailable(attribute); } /** @@ -96,10 +108,10 @@ export class ConfigProvider { try { this.config = await this.loadLocal(); this.initialised = true; - this.logger.log(`initialised configuration from storage: ${JSON.stringify(this.config)}`); + Logger.log(`initialised configuration from storage: ${JSON.stringify(this.config)}`); if (this.config.backend.SCVersion !== environment.backend_version) { loadError = new WrongConfigVersionInStorage(environment.backend_version, this.config.backend.SCVersion); - this.logger.warn(loadError); + Logger.warn(loadError); } } catch (error) { loadError = error; @@ -109,16 +121,18 @@ export class ConfigProvider { const fetchedConfig: SCIndexResponse = await this.fetch(); await this.set(fetchedConfig); this.initialised = true; - this.logger.log(`initialised configuration from remote: ${JSON.stringify(this.config)}`); + Logger.log(`initialised configuration from remote: ${JSON.stringify(this.config)}`); } catch (error) { fetchError = error; } // check for occurred errors and throw them if (typeof loadError !== 'undefined' && typeof fetchError !== 'undefined') { throw new ConfigInitError(); - } else if (typeof loadError !== 'undefined') { + } + if (typeof loadError !== 'undefined') { throw loadError; - } else if (typeof fetchError !== 'undefined') { + } + if (typeof fetchError !== 'undefined') { throw fetchError; } } @@ -132,7 +146,7 @@ export class ConfigProvider { await this.storageProvider.init(); // get local configuration if (await this.storageProvider.has(STORAGE_KEY_CONFIG)) { - return await this.storageProvider.get(STORAGE_KEY_CONFIG); + return this.storageProvider.get(STORAGE_KEY_CONFIG); } throw new SavedConfigNotAvailable(); } diff --git a/src/app/modules/data/data-facets.provider.ts b/src/app/modules/data/data-facets.provider.ts index 2760576f..2adc0feb 100644 --- a/src/app/modules/data/data-facets.provider.ts +++ b/src/app/modules/data/data-facets.provider.ts @@ -13,8 +13,11 @@ * this program. If not, see . */ import {Injectable} from '@angular/core'; -import {SCBackendAggregationConfiguration, SCFacet, SCThing, SCFacetBucket} from '@openstapps/core'; +import {SCBackendAggregationConfiguration, SCFacet, SCFacetBucket, SCThing} from '@openstapps/core'; +/** + * TODO + */ @Injectable() export class DataFacetsProvider { // tslint:disable-next-line:no-empty @@ -29,7 +32,8 @@ export class DataFacetsProvider { * @param bucketsMap Buckets array transformed into a map * @param fields A field that should be added to buckets (its map) */ - addBuckets(bucketsMap: {[key: string]: number}, fields: string[]): {[key: string]: number} { + // tslint:disable-next-line:prefer-function-over-method + addBuckets(bucketsMap: {[key: string]: number; }, fields: string[]): {[key: string]: number; } { fields.forEach((field) => { if (typeof bucketsMap[field] !== 'undefined') { bucketsMap[field] = bucketsMap[field] + 1; @@ -37,6 +41,7 @@ export class DataFacetsProvider { bucketsMap[field] = 1; } }); + return bucketsMap; } @@ -45,61 +50,16 @@ export class DataFacetsProvider { * * @param buckets Buckets from a facet */ - bucketsToMap(buckets: SCFacetBucket[]): {[key: string]: number} { - const bucketsMap: {[key: string]: number} = {}; + // tslint:disable-next-line:prefer-function-over-method + bucketsToMap(buckets: SCFacetBucket[]): {[key: string]: number; } { + const bucketsMap: {[key: string]: number; } = {}; buckets.forEach((bucket) => { bucketsMap[bucket.key] = bucket.count; }); + return bucketsMap; } - /** - * Converts a buckets map into buckets array (as it is inside of a facet) - * - * @param bucketsMap A map from a buckets array - */ - mapToBuckets(bucketsMap: {[key: string]: number}): SCFacetBucket[] { - const buckets: SCFacetBucket[] = []; - for (const key in bucketsMap) { - if (bucketsMap.hasOwnProperty(key)) { - const bucket: SCFacetBucket = {key: key, count: bucketsMap[key]}; - buckets.push(bucket); - } - } - return buckets; - } - - /** - * Converts facets array into a map (for quicker operations with facets) - * - * @param facets Array of facets - */ - facetsToMap(facets: SCFacet[]): {[key: string]: {[key: string]: number}} { - const facetsMap: {[key: string]: {[key: string]: number}} = {}; - facets.forEach((facet) => { - facetsMap[facet.field] = this.bucketsToMap(facet.buckets); - }); - return facetsMap; - } - - /** - * Converts facets map into an array of facets (as they are provided by backend) - * - * @param facetsMap A map from facets array - */ - mapToFacets(facetsMap: {[key: string]: {[key: string]: number}}): SCFacet[] { - const facets: SCFacet[] = []; - for (const key in facetsMap) { - if (facetsMap.hasOwnProperty(key)) { - const facet: SCFacet = {buckets: [], field: ''}; - facet.field = key; - facet.buckets = this.mapToBuckets(facetsMap[key]); - facets.push(facet); - } - } - return facets; - } - /** * Extract facets from data items, optionally combine them with a list of existing facets * @@ -114,12 +74,12 @@ export class DataFacetsProvider { if (items.length === 0) { if (facets.length === 0) { return []; - } else { - return facets; } + + return facets; } const combinedFacets: SCFacet[] = facets; - const combinedFacetsMap: {[key: string]: {[key: string]: number}} = this.facetsToMap(combinedFacets); + const combinedFacetsMap: {[key: string]: {[key: string]: number; }; } = this.facetsToMap(combinedFacets); (items as any[]).forEach((item) => { aggregations.forEach((aggregation) => { let fieldValues: string | string[] = item[aggregation.fieldName]; @@ -142,6 +102,58 @@ export class DataFacetsProvider { } }); }); + return this.mapToFacets(combinedFacetsMap); } + + /** + * Converts facets array into a map (for quicker operations with facets) + * + * @param facets Array of facets + */ + facetsToMap(facets: SCFacet[]): {[key: string]: {[key: string]: number; }; } { + const facetsMap: {[key: string]: {[key: string]: number; }; } = {}; + facets.forEach((facet) => { + facetsMap[facet.field] = this.bucketsToMap(facet.buckets); + }); + + return facetsMap; + } + + /** + * Converts a buckets map into buckets array (as it is inside of a facet) + * + * @param bucketsMap A map from a buckets array + */ + // tslint:disable-next-line:prefer-function-over-method + mapToBuckets(bucketsMap: {[key: string]: number; }): SCFacetBucket[] { + const buckets: SCFacetBucket[] = []; + for (const key in bucketsMap) { + if (bucketsMap.hasOwnProperty(key)) { + const bucket: SCFacetBucket = {key: key, count: bucketsMap[key]}; + buckets.push(bucket); + } + } + + return buckets; + } + + /** + * Converts facets map into an array of facets (as they are provided by backend) + * + * @param facetsMap A map from facets array + */ + mapToFacets(facetsMap: {[key: string]: {[key: string]: number; }; }): SCFacet[] { + const facets: SCFacet[] = []; + for (const key in facetsMap) { + if (facetsMap.hasOwnProperty(key)) { + const facet: SCFacet = {buckets: [], field: ''}; + facet.field = key; + facet.buckets = this.mapToBuckets(facetsMap[key]); + facets.push(facet); + } + } + + return facets; + } } diff --git a/src/app/modules/data/data-routing.module.ts b/src/app/modules/data/data-routing.module.ts index 6e6c16c6..674a1af8 100644 --- a/src/app/modules/data/data-routing.module.ts +++ b/src/app/modules/data/data-routing.module.ts @@ -22,6 +22,9 @@ const dataRoutes: Routes = [ {path: 'data-detail/:uid', component: DataDetailComponent}, ]; +/** + * TODO + */ @NgModule({ exports: [ RouterModule, diff --git a/src/app/modules/data/data.module.ts b/src/app/modules/data/data.module.ts index 1a5cf6f3..6b4cd967 100644 --- a/src/app/modules/data/data.module.ts +++ b/src/app/modules/data/data.module.ts @@ -26,13 +26,15 @@ import {DataRoutingModule} from './data-routing.module'; import {DataProvider} from './data.provider'; import {DataDetailContentComponent} from './detail/data-detail-content.component'; import {DataDetailComponent} from './detail/data-detail.component'; -import {OffersDetailComponent} from './elements/offers-detail.component'; -import {OffersInListComponent} from './elements/offers-in-list.component'; import {AddressDetailComponent} from './elements/address-detail.component'; import {LongInlineText} from './elements/long-inline-text.component'; +import {OffersDetailComponent} from './elements/offers-detail.component'; +import {OffersInListComponent} from './elements/offers-in-list.component'; import {OriginDetailComponent} from './elements/origin-detail.component'; import {OriginInListComponent} from './elements/origin-in-list.component'; import {SimpleCardComponent} from './elements/simple-card.component'; +import {SkeletonListItem} from './elements/skeleton-list-item.component'; +import {SkeletonSimpleCard} from './elements/skeleton-simple-card.component'; import {DataListItem} from './list/data-list-item.component'; import {DataListComponent} from './list/data-list.component'; import {StAppsWebHttpClient} from './stapps-web-http-client.provider'; @@ -60,9 +62,10 @@ import {SemesterDetailContentComponent} from './types/semester/semester-detail-c import {SemesterListItem} from './types/semester/semester-list-item.component'; import {VideoDetailContentComponent} from './types/video/video-detail-content.component'; import {VideoListItem} from './types/video/video-list-item.component'; -import {SkeletonListItem} from './elements/skeleton-list-item.component'; -import {SkeletonSimpleCard} from './elements/skeleton-simple-card.component'; +/** + * TODO + */ @NgModule({ declarations: [ OffersDetailComponent, diff --git a/src/app/modules/data/data.provider.ts b/src/app/modules/data/data.provider.ts index 186a1882..a6d4e28a 100644 --- a/src/app/modules/data/data.provider.ts +++ b/src/app/modules/data/data.provider.ts @@ -24,41 +24,64 @@ export enum DataScope { Remote = 'remote', } -/* - Generated class for the DataProvider provider. - - See https://angular.io/guide/dependency-injection for more info on providers - and Angular DI. -*/ +/** + * Generated class for the DataProvider provider. + * + * See https://angular.io/guide/dependency-injection for more info on providers + * and Angular DI. + */ @Injectable() export class DataProvider { - private _storagePrefix: string = 'stapps.data'; - // @TODO: get backendUrl and appVersion and storagePrefix from config (module) - appVersion: string = '1.0.6'; - backendUrl: string = 'http://localhost:3000'; + /** + * TODO + */ + private _storagePrefix = 'stapps.data'; + /** + * TODO + * + * @TODO: get backendUrl and appVersion and storagePrefix from config (module) + */ + appVersion = '1.0.6'; + /** + * TODO + */ + backendUrl = 'http://localhost:3000'; + /** + * TODO + */ client: Client; + /** + * TODO + */ storageProvider: StorageProvider; + /** + * TODO + * + * @param stAppsWebHttpClient TODO + * @param storageProvider TODO + */ constructor(stAppsWebHttpClient: StAppsWebHttpClient, storageProvider: StorageProvider) { this.client = new Client(stAppsWebHttpClient, this.backendUrl, this.appVersion); this.storageProvider = storageProvider; } - get storagePrefix(): string { - return this._storagePrefix; - } - - set storagePrefix(storagePrefix) { - this._storagePrefix = storagePrefix; + /** + * Delete a data item + * + * @param uid Unique identifier of the saved data item + */ + async delete(uid: string): Promise { + return this.storageProvider.delete(this.getDataKey(uid)); } /** - * Provides key for storing data into the local database - * - * @param uid Unique identifier of a resource + * Delete all the previously saved data items */ - getDataKey(uid: string): string { - return `${this.storagePrefix}.${uid}`; + async deleteAll(): Promise { + const keys = Array.from((await this.getAll()).keys()); + + return this.storageProvider.delete(...keys); } /** @@ -91,6 +114,7 @@ export class DataProvider { const map: Map> = new Map(); map.set(DataScope.Local, await this.get(uid, DataScope.Local)); map.set(DataScope.Remote, await this.get(uid, DataScope.Remote)); + return map; } @@ -101,6 +125,24 @@ export class DataProvider { return this.storageProvider.search>(this.storagePrefix); } + /** + * Provides key for storing data into the local database + * + * @param uid Unique identifier of a resource + */ + getDataKey(uid: string): string { + return `${this.storagePrefix}.${uid}`; + } + + /** + * Provides information if something with an UID is saved as a data item + * + * @param uid Unique identifier of the saved data item + */ + async isSaved(uid: string): Promise { + return this.storageProvider.has(this.getDataKey(uid)); + } + /** * Save a data item * @@ -118,25 +160,9 @@ export class DataProvider { type: (typeof type === 'undefined') ? item.type : type, uid: item.uid, }; + // @TODO: Implementation for saving item into the backend (user's account) - return (await this.storageProvider.put>(this.getDataKey(item.uid), saveableItem)); - } - - /** - * Delete a data item - * - * @param uid Unique identifier of the saved data item - */ - async delete(uid: string): Promise { - return this.storageProvider.delete(this.getDataKey(uid)); - } - - /** - * Delete all the previously saved data items - */ - async deleteAll(): Promise { - const keys = Array.from((await this.getAll()).keys()); - return this.storageProvider.delete(...keys); + return ( this.storageProvider.put>(this.getDataKey(item.uid), saveableItem)); } /** @@ -145,15 +171,20 @@ export class DataProvider { * @param query - query to send to the backend */ async search(query: SCSearchQuery): Promise { - return (await this.client.search(query)); + return (this.client.search(query)); } /** - * Provides information if something with an UID is saved as a data item - * - * @param uid Unique identifier of the saved data item + * TODO */ - async isSaved(uid: string): Promise { - return this.storageProvider.has(this.getDataKey(uid)); + get storagePrefix(): string { + return this._storagePrefix; + } + + /** + * TODO + */ + set storagePrefix(storagePrefix) { + this._storagePrefix = storagePrefix; } } diff --git a/src/app/modules/data/detail/data-detail-content.component.ts b/src/app/modules/data/detail/data-detail-content.component.ts index 4095a7d5..6dc7d06f 100644 --- a/src/app/modules/data/detail/data-detail-content.component.ts +++ b/src/app/modules/data/detail/data-detail-content.component.ts @@ -15,10 +15,16 @@ import {Component, Input} from '@angular/core'; import {SCThings} from '@openstapps/core'; +/** + * TODO + */ @Component({ selector: 'stapps-data-detail-content', templateUrl: 'data-detail-content.html', }) export class DataDetailContentComponent { + /** + * TODO + */ @Input() item: SCThings; } diff --git a/src/app/modules/data/detail/data-detail.component.ts b/src/app/modules/data/detail/data-detail.component.ts index 78546930..6905a0d0 100644 --- a/src/app/modules/data/detail/data-detail.component.ts +++ b/src/app/modules/data/detail/data-detail.component.ts @@ -19,17 +19,35 @@ import {LangChangeEvent, TranslateService} from '@ngx-translate/core'; import {SCLanguageCode, SCThing, SCUuid} from '@openstapps/core'; import {DataProvider, DataScope} from '../data.provider'; +/** + * TODO + */ @Component({ selector: 'stapps-data-detail', styleUrls: ['data-detail.scss'], templateUrl: 'data-detail.html', }) export class DataDetailComponent { + /** + * TODO + */ dataProvider: DataProvider; + /** + * TODO + */ item: SCThing; + /** + * TODO + */ language: SCLanguageCode; - constructor(private route: ActivatedRoute, dataProvider: DataProvider, translateService: TranslateService) { + /** + * + * @param route TODO + * @param dataProvider TODO + * @param translateService TODO + */ + constructor(private readonly route: ActivatedRoute, dataProvider: DataProvider, translateService: TranslateService) { this.dataProvider = dataProvider; this.language = translateService.currentLang as SCLanguageCode; translateService.onLangChange.subscribe((event: LangChangeEvent) => { @@ -43,11 +61,16 @@ export class DataDetailComponent { * @param uid Unique identifier of a thing */ async getItem(uid: SCUuid): Promise { - this.dataProvider.get(uid, DataScope.Remote).then((data) => { + await this.dataProvider.get(uid, DataScope.Remote) + .then((data) => { this.item = data; - }); + }); } + /** + * TODO + */ + // tslint:disable-next-line:prefer-function-over-method ngOnInit() { this.getItem(this.route.snapshot.paramMap.get('uid') || ''); } diff --git a/src/app/modules/data/elements/address-detail.component.ts b/src/app/modules/data/elements/address-detail.component.ts index 28c47ddf..585279e3 100644 --- a/src/app/modules/data/elements/address-detail.component.ts +++ b/src/app/modules/data/elements/address-detail.component.ts @@ -15,10 +15,16 @@ import {Component, Input} from '@angular/core'; import {SCPostalAddress} from '@openstapps/core'; +/** + * TODO + */ @Component({ selector: 'stapps-address-detail', templateUrl: 'address-detail.html', }) export class AddressDetailComponent { + /** + * TODO + */ @Input() address: SCPostalAddress; } diff --git a/src/app/modules/data/elements/long-inline-text.component.ts b/src/app/modules/data/elements/long-inline-text.component.ts index 87d8d2d8..9314b269 100644 --- a/src/app/modules/data/elements/long-inline-text.component.ts +++ b/src/app/modules/data/elements/long-inline-text.component.ts @@ -14,11 +14,20 @@ */ import {Component, Input} from '@angular/core'; +/** + * TODO + */ @Component({ selector: 'stapps-long-inline-text', templateUrl: 'long-inline-text.html', }) export class LongInlineText { - @Input() text: string; + /** + * TODO + */ @Input() size: number; + /** + * TODO + */ + @Input() text: string; } diff --git a/src/app/modules/data/elements/offers-detail.component.ts b/src/app/modules/data/elements/offers-detail.component.ts index 0fbd1444..94fb390e 100644 --- a/src/app/modules/data/elements/offers-detail.component.ts +++ b/src/app/modules/data/elements/offers-detail.component.ts @@ -15,11 +15,20 @@ import {Component, Input} from '@angular/core'; import {SCAcademicPriceGroup, SCThingThatCanBeOfferedOffer} from '@openstapps/core'; +/** + * TODO + */ @Component({ selector: 'stapps-offers-detail', templateUrl: 'offers-detail.html', }) export class OffersDetailComponent { + /** + * TODO + */ objectKeys = Object.keys; + /** + * TODO + */ @Input() offers: Array>; } diff --git a/src/app/modules/data/elements/offers-in-list.component.ts b/src/app/modules/data/elements/offers-in-list.component.ts index c5ab3eab..38dbe4eb 100644 --- a/src/app/modules/data/elements/offers-in-list.component.ts +++ b/src/app/modules/data/elements/offers-in-list.component.ts @@ -15,10 +15,16 @@ import {Component, Input} from '@angular/core'; import {SCAcademicPriceGroup, SCThingThatCanBeOfferedOffer} from '@openstapps/core'; +/** + * TODO + */ @Component({ selector: 'stapps-offers-in-list', templateUrl: 'offers-in-list.html', }) export class OffersInListComponent { + /** + * TODO + */ @Input() offers: Array>; } diff --git a/src/app/modules/data/elements/origin-detail.component.ts b/src/app/modules/data/elements/origin-detail.component.ts index 9aac3a43..c9c46647 100644 --- a/src/app/modules/data/elements/origin-detail.component.ts +++ b/src/app/modules/data/elements/origin-detail.component.ts @@ -15,10 +15,16 @@ import {Component, Input} from '@angular/core'; import {SCThingOrigin} from '@openstapps/core'; +/** + * TODO + */ @Component({ selector: 'stapps-origin-detail', templateUrl: 'origin-detail.html', }) export class OriginDetailComponent { + /** + * TODO + */ @Input() origin: SCThingOrigin; } diff --git a/src/app/modules/data/elements/origin-in-list.component.ts b/src/app/modules/data/elements/origin-in-list.component.ts index 966ca218..810d1cfc 100644 --- a/src/app/modules/data/elements/origin-in-list.component.ts +++ b/src/app/modules/data/elements/origin-in-list.component.ts @@ -15,10 +15,16 @@ import {Component, Input} from '@angular/core'; import {SCThingOrigin} from '@openstapps/core'; +/** + * TODO + */ @Component({ selector: 'stapps-origin-in-list', templateUrl: 'origin-in-list.html', }) export class OriginInListComponent { + /** + * TODO + */ @Input() origin: SCThingOrigin; } diff --git a/src/app/modules/data/elements/simple-card.component.ts b/src/app/modules/data/elements/simple-card.component.ts index 05125ac5..3e97927a 100644 --- a/src/app/modules/data/elements/simple-card.component.ts +++ b/src/app/modules/data/elements/simple-card.component.ts @@ -15,18 +15,41 @@ import {Component, Input} from '@angular/core'; import {isThing, SCThing} from '@openstapps/core'; +/** + * TODO + */ @Component({ selector: 'stapps-simple-card', templateUrl: 'simple-card.html', }) export class SimpleCardComponent { - areThings: boolean = false; + /** + * TODO + */ + areThings = false; + /** + * TODO + */ @Input() content: string | string[] | SCThing[]; - @Input() isMarkdown: boolean = false; + /** + * TODO + */ + @Input() isMarkdown = false; + /** + * TODO + */ @Input() title: string; + /** + * TODO + */ + // tslint:disable-next-line:prefer-function-over-method isString(data: any): data is string { return typeof data === 'string'; } + /** + * TODO + */ + // tslint:disable-next-line:prefer-function-over-method isThing(something: any): something is SCThing { return isThing(something); } diff --git a/src/app/modules/data/elements/skeleton-list-item.component.ts b/src/app/modules/data/elements/skeleton-list-item.component.ts index 72caf897..68f48e4b 100644 --- a/src/app/modules/data/elements/skeleton-list-item.component.ts +++ b/src/app/modules/data/elements/skeleton-list-item.component.ts @@ -14,6 +14,9 @@ */ import {Component} from '@angular/core'; +/** + * TODO + */ @Component({ selector: 'stapps-skeleton-list-item', templateUrl: 'skeleton-list-item.html', diff --git a/src/app/modules/data/elements/skeleton-simple-card.component.ts b/src/app/modules/data/elements/skeleton-simple-card.component.ts index a73f1920..b653a595 100644 --- a/src/app/modules/data/elements/skeleton-simple-card.component.ts +++ b/src/app/modules/data/elements/skeleton-simple-card.component.ts @@ -14,6 +14,9 @@ */ import {Component} from '@angular/core'; +/** + * TODO + */ @Component({ selector: 'stapps-skeleton-simple-card', templateUrl: 'skeleton-simple-card.html', diff --git a/src/app/modules/data/list/data-list-item.component.ts b/src/app/modules/data/list/data-list-item.component.ts index 9364335a..dccc8321 100644 --- a/src/app/modules/data/list/data-list-item.component.ts +++ b/src/app/modules/data/list/data-list-item.component.ts @@ -15,19 +15,32 @@ import {Component, Input, OnInit} from '@angular/core'; import {SCThings} from '@openstapps/core'; +/** + * TODO + */ @Component({ selector: 'stapps-data-list-item', styleUrls: ['data-list-item.scss'], templateUrl: 'data-list-item.html', }) export class DataListItem implements OnInit { + /** + * TODO + */ @Input() item: SCThings; + /** + * TODO + */ constructor() { // noop // this.item is not available yet } + /** + * TODO + */ + // tslint:disable-next-line:prefer-function-over-method ngOnInit() { // noop // this.item is available now - the template is loaded and compiled diff --git a/src/app/modules/data/list/data-list.component.ts b/src/app/modules/data/list/data-list.component.ts index f750f837..ef060901 100644 --- a/src/app/modules/data/list/data-list.component.ts +++ b/src/app/modules/data/list/data-list.component.ts @@ -19,24 +19,58 @@ import {Subject} from 'rxjs'; import {debounceTime, distinctUntilChanged} from 'rxjs/operators'; import {DataProvider} from '../data.provider'; +/** + * TODO + */ @Component({ selector: 'stapps-data-list', templateUrl: 'data-list.html', }) export class DataListComponent { + /** + * TODO + */ dataProvider: DataProvider; + /** + * TODO + */ + from = 0; + + /** + * TODO + */ items: SCThing[]; - selectedItem: any; - loaded: boolean = false; - size: number = 30; - from: number = 0; + /** + * TODO + */ + loaded = false; + /** + * TODO + */ query: string; + /** + * TODO + */ queryChanged: Subject = new Subject(); + /** + * TODO + */ + selectedItem: any; + /** + * TODO + */ + size = 30; + + /** + * + * @param alertController TODO + * @param dataProvider TODO + */ constructor( - private alertController: AlertController, + private readonly alertController: AlertController, dataProvider: DataProvider, ) { this.dataProvider = dataProvider; @@ -52,31 +86,41 @@ export class DataListComponent { this.fetchItems(); } + /** + * TODO + */ private async fetchItems(): Promise { return this.dataProvider.search({ from: this.from, query: this.query, size: this.size, - } as any).then((result) => { - this.items = result.data; - this.loaded = true; - }, async (err) => { - const alert: HTMLIonAlertElement = await this.alertController.create({ - buttons: ['Dismiss'], - header: 'Error', - subHeader: err.message, - }); + } as any) + .then((result) => { + this.items = result.data; + this.loaded = true; + }, async (err) => { + const alert: HTMLIonAlertElement = await this.alertController.create({ + buttons: ['Dismiss'], + header: 'Error', + subHeader: err.message, + }); - await alert.present(); - }); + await alert.present(); + }); } + /** + * TODO + */ async loadMore(event: any): Promise { this.from += this.size; await this.fetchItems(); event.target.complete(); } + /** + * TODO + */ search(query: string) { this.queryChanged.next(query); } diff --git a/src/app/modules/data/stapps-web-http-client.provider.ts b/src/app/modules/data/stapps-web-http-client.provider.ts index 41681a90..3b9a58a0 100644 --- a/src/app/modules/data/stapps-web-http-client.provider.ts +++ b/src/app/modules/data/stapps-web-http-client.provider.ts @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 StApps + * 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. @@ -14,15 +14,18 @@ */ import {HttpClient, HttpResponse} from '@angular/common/http'; import {Injectable} from '@angular/core'; -import {HttpClientInterface} from '@openstapps/api/lib/httpClientInterface'; -import {HttpClientRequest} from '@openstapps/api/lib/httpClientInterface'; +import {HttpClientInterface, HttpClientRequest} from '@openstapps/api/lib/http-client-interface'; /** * HttpClient that is based on angular's HttpClient (@TODO: move it to provider or independent package) */ @Injectable() export class StAppsWebHttpClient implements HttpClientInterface { - constructor(private http: HttpClient) { + /** + * + * @param http TODO + */ + constructor(private readonly http: HttpClient) { } /** @@ -33,7 +36,13 @@ export class StAppsWebHttpClient implements HttpClientInterface { requestConfig: HttpClientRequest, ): Promise> { const options: { + /** + * TODO + */ [key: string]: any; + /** + * TODO + */ observe: 'response'; } = { body: {}, @@ -53,6 +62,7 @@ export class StAppsWebHttpClient implements HttpClientInterface { const response: HttpResponse = await this.http.request( requestConfig.method || 'GET', requestConfig.url.toString(), options) .toPromise(); + return Object.assign(response, {statusCode: response.status, body: response.body || {}}); } catch (err) { throw Error(err); @@ -64,6 +74,12 @@ export class StAppsWebHttpClient implements HttpClientInterface { * Response with generic for the type of body that is returned from the request */ export interface Response extends HttpResponse { + /** + * TODO + */ body: TYPE_OF_BODY; + /** + * TODO + */ statusCode: number; } diff --git a/src/app/modules/data/types/article/article-detail-content.component.ts b/src/app/modules/data/types/article/article-detail-content.component.ts index 47494977..2b37313b 100644 --- a/src/app/modules/data/types/article/article-detail-content.component.ts +++ b/src/app/modules/data/types/article/article-detail-content.component.ts @@ -16,16 +16,34 @@ import {Component, Input} from '@angular/core'; import {SCArticle, SCThing, SCTranslations} from '@openstapps/core'; import {SCThingTranslator} from '@openstapps/core'; +/** + * TODO + */ @Component({ selector: 'stapps-article-detail-content', templateUrl: 'article-detail-content.html', }) export class ArticleDetailContentComponent { + /** + * TODO + */ @Input() item: SCArticle; + /** + * TODO + */ @Input() language: keyof SCTranslations; + /** + * TODO + */ objectKeys = Object.keys; + /** + * TODO + */ translator: SCThingTranslator; + /** + * TODO + */ constructor() { - this.translator = new SCThingTranslator(this.language, 'de'); + this.translator = new SCThingTranslator(this.language); } } diff --git a/src/app/modules/data/types/article/article-list-item.component.ts b/src/app/modules/data/types/article/article-list-item.component.ts index af0b39a6..20f2629a 100644 --- a/src/app/modules/data/types/article/article-list-item.component.ts +++ b/src/app/modules/data/types/article/article-list-item.component.ts @@ -16,14 +16,24 @@ import {Component, Input} from '@angular/core'; import {SCArticle} from '@openstapps/core'; import {DataListItem} from '../../list/data-list-item.component'; +/** + * TODO + */ @Component({ selector: 'stapps-article-list-item', templateUrl: 'article-list-item.html', }) export class ArticleListItem extends DataListItem { + /** + * TODO + */ @Input() item: SCArticle; + /** + * TODO + */ + // tslint:disable-next-line:prefer-function-over-method ngOnInit() { // TODO: translation } diff --git a/src/app/modules/data/types/catalog/catalog-detail-content.component.ts b/src/app/modules/data/types/catalog/catalog-detail-content.component.ts index ee09c206..01e5233c 100644 --- a/src/app/modules/data/types/catalog/catalog-detail-content.component.ts +++ b/src/app/modules/data/types/catalog/catalog-detail-content.component.ts @@ -16,16 +16,34 @@ import {Component, Input} from '@angular/core'; import {SCCatalog, SCThing, SCTranslations} from '@openstapps/core'; import {SCThingTranslator} from '@openstapps/core'; +/** + * TODO + */ @Component({ selector: 'stapps-catalog-detail-content', templateUrl: 'catalog-detail-content.html', }) export class CatalogDetailContentComponent { + /** + * TODO + */ @Input() item: SCCatalog; + /** + * TODO + */ @Input() language: keyof SCTranslations; + /** + * TODO + */ objectKeys = Object.keys; + /** + * TODO + */ translator: SCThingTranslator; + /** + * TODO + */ constructor() { - this.translator = new SCThingTranslator(this.language, 'de'); + this.translator = new SCThingTranslator(this.language); } } diff --git a/src/app/modules/data/types/catalog/catalog-list-item.component.ts b/src/app/modules/data/types/catalog/catalog-list-item.component.ts index 9b3fff29..90dc552a 100644 --- a/src/app/modules/data/types/catalog/catalog-list-item.component.ts +++ b/src/app/modules/data/types/catalog/catalog-list-item.component.ts @@ -16,14 +16,24 @@ import {Component, Input} from '@angular/core'; import {SCCatalog} from '@openstapps/core'; import {DataListItem} from '../../list/data-list-item.component'; +/** + * TODO + */ @Component({ selector: 'stapps-catalog-list-item', templateUrl: 'catalog-list-item.html', }) export class CatalogListItem extends DataListItem { + /** + * TODO + */ @Input() item: SCCatalog; + /** + * TODO + */ + // tslint:disable-next-line:prefer-function-over-method ngOnInit() { // TODO: translation } diff --git a/src/app/modules/data/types/date-series/date-series-detail-content.component.ts b/src/app/modules/data/types/date-series/date-series-detail-content.component.ts index c2eba501..87d4338a 100644 --- a/src/app/modules/data/types/date-series/date-series-detail-content.component.ts +++ b/src/app/modules/data/types/date-series/date-series-detail-content.component.ts @@ -16,16 +16,34 @@ import {Component, Input} from '@angular/core'; import {SCDateSeries, SCThing, SCTranslations} from '@openstapps/core'; import {SCThingTranslator} from '@openstapps/core'; +/** + * TODO + */ @Component({ selector: 'stapps-date-series-detail-content', templateUrl: 'date-series-detail-content.html', }) export class DateSeriesDetailContentComponent { + /** + * TODO + */ @Input() item: SCDateSeries; + /** + * TODO + */ @Input() language: keyof SCTranslations; + /** + * TODO + */ objectKeys = Object.keys; + /** + * TODO + */ translator: SCThingTranslator; + /** + * TODO + */ constructor() { - this.translator = new SCThingTranslator(this.language, 'de'); + this.translator = new SCThingTranslator(this.language); } } diff --git a/src/app/modules/data/types/date-series/date-series-list-item.component.ts b/src/app/modules/data/types/date-series/date-series-list-item.component.ts index ca1a0a65..d5a6beb1 100644 --- a/src/app/modules/data/types/date-series/date-series-list-item.component.ts +++ b/src/app/modules/data/types/date-series/date-series-list-item.component.ts @@ -16,14 +16,24 @@ import {Component, Input} from '@angular/core'; import {SCDateSeries} from '@openstapps/core'; import {DataListItem} from '../../list/data-list-item.component'; +/** + * TODO + */ @Component({ selector: 'stapps-date-series-list-item', templateUrl: 'date-series-list-item.html', }) export class DateSeriesListItem extends DataListItem { + /** + * TODO + */ @Input() item: SCDateSeries; + /** + * TODO + */ + // tslint:disable-next-line:prefer-function-over-method ngOnInit() { // TODO: translation } diff --git a/src/app/modules/data/types/dish/dish-detail-content.component.ts b/src/app/modules/data/types/dish/dish-detail-content.component.ts index d235397e..ea34ef2f 100644 --- a/src/app/modules/data/types/dish/dish-detail-content.component.ts +++ b/src/app/modules/data/types/dish/dish-detail-content.component.ts @@ -16,16 +16,34 @@ import {Component, Input} from '@angular/core'; import {SCDish, SCThing, SCTranslations} from '@openstapps/core'; import {SCThingTranslator} from '@openstapps/core'; +/** + * TODO + */ @Component({ selector: 'stapps-dish-detail-content', templateUrl: 'dish-detail-content.html', }) export class DishDetailContentComponent { + /** + * TODO + */ @Input() item: SCDish; + /** + * TODO + */ @Input() language: keyof SCTranslations; + /** + * TODO + */ objectKeys = Object.keys; + /** + * TODO + */ translator: SCThingTranslator; + /** + * TODO + */ constructor() { - this.translator = new SCThingTranslator(this.language, 'de'); + this.translator = new SCThingTranslator(this.language); } } diff --git a/src/app/modules/data/types/dish/dish-list-item.component.ts b/src/app/modules/data/types/dish/dish-list-item.component.ts index a7fa6895..7622ec6b 100644 --- a/src/app/modules/data/types/dish/dish-list-item.component.ts +++ b/src/app/modules/data/types/dish/dish-list-item.component.ts @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 StApps + * 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. @@ -17,12 +17,18 @@ import {SCDish} from '@openstapps/core'; // import {SettingsProvider} from '../../../settings/settings.provider'; import {DataListItem} from '../../list/data-list-item.component'; +/** + * TODO + */ @Component({ selector: 'stapps-dish-list-item', templateUrl: 'dish-list-item.html', }) export class DishListItem extends DataListItem { + /** + * TODO + */ @Input() item: SCDish; // settingsProvider: SettingsProvider; @@ -31,6 +37,10 @@ export class DishListItem extends DataListItem { // this.settingsProvider = settingsProvider; // } + /** + * TODO + */ + // tslint:disable-next-line:prefer-function-over-method ngOnInit() { // TODO: translation... } diff --git a/src/app/modules/data/types/event/event-detail-content.component.ts b/src/app/modules/data/types/event/event-detail-content.component.ts index 69603ecc..b6c3c012 100644 --- a/src/app/modules/data/types/event/event-detail-content.component.ts +++ b/src/app/modules/data/types/event/event-detail-content.component.ts @@ -16,16 +16,34 @@ import {Component, Input} from '@angular/core'; import {SCAcademicEvent, SCSportCourse, SCThing, SCTranslations} from '@openstapps/core'; import {SCThingTranslator} from '@openstapps/core'; +/** + * TODO + */ @Component({ selector: 'stapps-event-detail-content', templateUrl: 'event-detail-content.html', }) export class EventDetailContentComponent { + /** + * TODO + */ @Input() item: SCAcademicEvent | SCSportCourse; + /** + * TODO + */ @Input() language: keyof SCTranslations; + /** + * TODO + */ objectKeys = Object.keys; + /** + * TODO + */ translator: SCThingTranslator; + /** + * TODO + */ constructor() { - this.translator = new SCThingTranslator(this.language, 'de'); + this.translator = new SCThingTranslator(this.language); } } diff --git a/src/app/modules/data/types/event/event-list-item.component.ts b/src/app/modules/data/types/event/event-list-item.component.ts index 9d29282e..d301402b 100644 --- a/src/app/modules/data/types/event/event-list-item.component.ts +++ b/src/app/modules/data/types/event/event-list-item.component.ts @@ -16,13 +16,23 @@ import {Component, Input} from '@angular/core'; import {SCAcademicEvent, SCSportCourse} from '@openstapps/core'; import {DataListItem} from '../../list/data-list-item.component'; +/** + * TODO + */ @Component({ selector: 'stapps-event-list-item', templateUrl: 'event-list-item.html', }) export class EventListItemComponent extends DataListItem { + /** + * TODO + */ @Input() item: SCAcademicEvent | SCSportCourse; + /** + * TODO + */ + // tslint:disable-next-line:prefer-function-over-method ngOnInit() { // TODO: translation } diff --git a/src/app/modules/data/types/favorite/favorite-detail-content.component.ts b/src/app/modules/data/types/favorite/favorite-detail-content.component.ts index 5fc441a8..baba11a4 100644 --- a/src/app/modules/data/types/favorite/favorite-detail-content.component.ts +++ b/src/app/modules/data/types/favorite/favorite-detail-content.component.ts @@ -16,16 +16,34 @@ import {Component, Input} from '@angular/core'; import {SCFavorite, SCThing, SCTranslations} from '@openstapps/core'; import {SCThingTranslator} from '@openstapps/core'; +/** + * TODO + */ @Component({ selector: 'stapps-favorite-detail-content', templateUrl: 'favorite-detail-content.html', }) export class FavoriteDetailContentComponent { + /** + * TODO + */ @Input() item: SCFavorite; + /** + * TODO + */ @Input() language: keyof SCTranslations; + /** + * TODO + */ objectKeys = Object.keys; + /** + * TODO + */ translator: SCThingTranslator; + /** + * TODO + */ constructor() { - this.translator = new SCThingTranslator(this.language, 'de'); + this.translator = new SCThingTranslator(this.language); } } diff --git a/src/app/modules/data/types/favorite/favorite-list-item.component.ts b/src/app/modules/data/types/favorite/favorite-list-item.component.ts index ddb3b228..923d047b 100644 --- a/src/app/modules/data/types/favorite/favorite-list-item.component.ts +++ b/src/app/modules/data/types/favorite/favorite-list-item.component.ts @@ -16,14 +16,24 @@ import {Component, Input} from '@angular/core'; import {SCFavorite} from '@openstapps/core'; import {DataListItem} from '../../list/data-list-item.component'; +/** + * TODO + */ @Component({ selector: 'stapps-favorite-list-item', templateUrl: 'favorite-list-item.html', }) export class FavoriteListItem extends DataListItem { + /** + * TODO + */ @Input() item: SCFavorite; + /** + * TODO + */ + // tslint:disable-next-line:prefer-function-over-method ngOnInit() { // TODO: translation } diff --git a/src/app/modules/data/types/message/message-detail-content.component.ts b/src/app/modules/data/types/message/message-detail-content.component.ts index e9b4284d..904cb26e 100644 --- a/src/app/modules/data/types/message/message-detail-content.component.ts +++ b/src/app/modules/data/types/message/message-detail-content.component.ts @@ -16,16 +16,34 @@ import {Component, Input} from '@angular/core'; import {SCMessage, SCThing, SCTranslations} from '@openstapps/core'; import {SCThingTranslator} from '@openstapps/core'; +/** + * TODO + */ @Component({ selector: 'stapps-message-detail-content', templateUrl: 'message-detail-content.html', }) export class MessageDetailContentComponent { + /** + * TODO + */ @Input() item: SCMessage; + /** + * TODO + */ @Input() language: keyof SCTranslations; + /** + * TODO + */ objectKeys = Object.keys; + /** + * TODO + */ translator: SCThingTranslator; + /** + * TODO + */ constructor() { - this.translator = new SCThingTranslator(this.language, 'de'); + this.translator = new SCThingTranslator(this.language); } } diff --git a/src/app/modules/data/types/message/message-detail-content.html b/src/app/modules/data/types/message/message-detail-content.html index e9b5cfd3..a3e670fc 100644 --- a/src/app/modules/data/types/message/message-detail-content.html +++ b/src/app/modules/data/types/message/message-detail-content.html @@ -1,4 +1,4 @@ - + diff --git a/src/app/modules/data/types/message/message-list-item.component.ts b/src/app/modules/data/types/message/message-list-item.component.ts index 658c03c1..6228885b 100644 --- a/src/app/modules/data/types/message/message-list-item.component.ts +++ b/src/app/modules/data/types/message/message-list-item.component.ts @@ -16,14 +16,24 @@ import {Component, Input} from '@angular/core'; import {SCMessage} from '@openstapps/core'; import {DataListItem} from '../../list/data-list-item.component'; +/** + * TODO + */ @Component({ selector: 'stapps-message-list-item', templateUrl: 'message-list-item.html', }) export class MessageListItem extends DataListItem { + /** + * TODO + */ @Input() item: SCMessage; + /** + * TODO + */ + // tslint:disable-next-line:prefer-function-over-method ngOnInit() { // TODO: translation } diff --git a/src/app/modules/data/types/message/message-list-item.html b/src/app/modules/data/types/message/message-list-item.html index 40de0c58..9b6b6c06 100644 --- a/src/app/modules/data/types/message/message-list-item.html +++ b/src/app/modules/data/types/message/message-list-item.html @@ -2,8 +2,8 @@

{{item.name}}

-

- +

+

{{item.type}}
diff --git a/src/app/modules/data/types/organization/organization-detail-content.component.ts b/src/app/modules/data/types/organization/organization-detail-content.component.ts index 3012bb50..53642c6c 100644 --- a/src/app/modules/data/types/organization/organization-detail-content.component.ts +++ b/src/app/modules/data/types/organization/organization-detail-content.component.ts @@ -16,16 +16,35 @@ import {Component, Input} from '@angular/core'; import {SCOrganization, SCThing, SCTranslations} from '@openstapps/core'; import {SCThingTranslator} from '@openstapps/core'; +/** + * TODO + */ @Component({ selector: 'stapps-organization-detail-content', templateUrl: 'organization-detail-content.html', }) export class OrganizationDetailContentComponent { + /** + * TODO + */ @Input() item: SCOrganization; + /** + * TODO + */ @Input() language: keyof SCTranslations; + /** + * TODO + */ objectKeys = Object.keys; + /** + * TODO + */ translator: SCThingTranslator; + + /** + * TODO + */ constructor() { - this.translator = new SCThingTranslator(this.language, 'de'); + this.translator = new SCThingTranslator(this.language); } } diff --git a/src/app/modules/data/types/organization/organization-list-item.component.ts b/src/app/modules/data/types/organization/organization-list-item.component.ts index 1c8b971f..7753c234 100644 --- a/src/app/modules/data/types/organization/organization-list-item.component.ts +++ b/src/app/modules/data/types/organization/organization-list-item.component.ts @@ -16,14 +16,24 @@ import {Component, Input} from '@angular/core'; import {SCOrganization} from '@openstapps/core'; import {DataListItem} from '../../list/data-list-item.component'; +/** + * TODO + */ @Component({ selector: 'stapps-organization-list-item', templateUrl: 'organization-list-item.html', }) export class OrganizationListItem extends DataListItem { + /** + * TODO + */ @Input() item: SCOrganization; + /** + * TODO + */ + // tslint:disable-next-line:prefer-function-over-method ngOnInit() { // TODO: translation } diff --git a/src/app/modules/data/types/person/person-detail-content.component.ts b/src/app/modules/data/types/person/person-detail-content.component.ts index 000c8ddb..5f0c57e6 100644 --- a/src/app/modules/data/types/person/person-detail-content.component.ts +++ b/src/app/modules/data/types/person/person-detail-content.component.ts @@ -16,16 +16,35 @@ import {Component, Input} from '@angular/core'; import {SCPerson, SCThing, SCTranslations} from '@openstapps/core'; import {SCThingTranslator} from '@openstapps/core'; +/** + * TODO + */ @Component({ selector: 'stapps-person-detail-content', templateUrl: 'person-detail-content.html', }) export class PersonDetailContentComponent { + /** + * TODO + */ @Input() item: SCPerson; + /** + * TODO + */ @Input() language: keyof SCTranslations; + /** + * TODO + */ objectKeys = Object.keys; + /** + * TODO + */ translator: SCThingTranslator; + + /** + * TODO + */ constructor() { - this.translator = new SCThingTranslator(this.language, 'de'); + this.translator = new SCThingTranslator(this.language); } } diff --git a/src/app/modules/data/types/person/person-list-item.component.ts b/src/app/modules/data/types/person/person-list-item.component.ts index 14609879..ce08f258 100644 --- a/src/app/modules/data/types/person/person-list-item.component.ts +++ b/src/app/modules/data/types/person/person-list-item.component.ts @@ -16,14 +16,24 @@ import {Component, Input} from '@angular/core'; import {SCPerson} from '@openstapps/core'; import {DataListItem} from '../../list/data-list-item.component'; +/** + * TODO + */ @Component({ selector: 'stapps-person-list-item', templateUrl: 'person-list-item.html', }) export class PersonListItem extends DataListItem { + /** + * TODO + */ @Input() item: SCPerson; + /** + * TODO + */ + // tslint:disable-next-line:prefer-function-over-method ngOnInit() { // TODO: translation } diff --git a/src/app/modules/data/types/place/place-detail-content.component.ts b/src/app/modules/data/types/place/place-detail-content.component.ts index 85a48109..f265f5c7 100644 --- a/src/app/modules/data/types/place/place-detail-content.component.ts +++ b/src/app/modules/data/types/place/place-detail-content.component.ts @@ -16,16 +16,35 @@ import {Component, Input} from '@angular/core'; import {SCBuilding, SCFloor, SCPointOfInterest, SCRoom, SCThing, SCTranslations} from '@openstapps/core'; import {SCThingTranslator} from '@openstapps/core'; +/** + * TODO + */ @Component({ selector: 'stapps-place-detail-content', templateUrl: 'place-detail-content.html', }) export class PlaceDetailContentComponent { + /** + * TODO + */ @Input() item: SCBuilding | SCRoom | SCPointOfInterest | SCFloor; + /** + * TODO + */ @Input() language: keyof SCTranslations; + /** + * TODO + */ objectKeys = Object.keys; + /** + * TODO + */ translator: SCThingTranslator; + + /** + * TODO + */ constructor() { - this.translator = new SCThingTranslator(this.language, 'de'); + this.translator = new SCThingTranslator(this.language); } } diff --git a/src/app/modules/data/types/place/place-list-item.component.ts b/src/app/modules/data/types/place/place-list-item.component.ts index 98054dbb..813c0d1e 100644 --- a/src/app/modules/data/types/place/place-list-item.component.ts +++ b/src/app/modules/data/types/place/place-list-item.component.ts @@ -16,14 +16,24 @@ import {Component, Input} from '@angular/core'; import {SCBuilding, SCFloor, SCPointOfInterest, SCRoom} from '@openstapps/core'; import {DataListItem} from '../../list/data-list-item.component'; +/** + * TODO + */ @Component({ selector: 'stapps-place-list-item', templateUrl: 'place-list-item.html', }) export class PlaceListItem extends DataListItem { + /** + * TODO + */ @Input() item: SCBuilding | SCRoom | SCPointOfInterest | SCFloor; + /** + * TODO + */ + // tslint:disable-next-line:prefer-function-over-method ngOnInit() { // TODO: translation } diff --git a/src/app/modules/data/types/semester/semester-detail-content.component.ts b/src/app/modules/data/types/semester/semester-detail-content.component.ts index 6e1dad53..d7b680f9 100644 --- a/src/app/modules/data/types/semester/semester-detail-content.component.ts +++ b/src/app/modules/data/types/semester/semester-detail-content.component.ts @@ -16,16 +16,35 @@ import {Component, Input} from '@angular/core'; import {SCSemester, SCThing, SCTranslations} from '@openstapps/core'; import {SCThingTranslator} from '@openstapps/core'; +/** + * TODO + */ @Component({ selector: 'stapps-semester-detail-content', templateUrl: 'semester-detail-content.html', }) export class SemesterDetailContentComponent { + /** + * TODO + */ @Input() item: SCSemester; + /** + * TODO + */ @Input() language: keyof SCTranslations; + /** + * TODO + */ objectKeys = Object.keys; + /** + * TODO + */ translator: SCThingTranslator; + + /** + * TODO + */ constructor() { - this.translator = new SCThingTranslator(this.language, 'de'); + this.translator = new SCThingTranslator(this.language); } } diff --git a/src/app/modules/data/types/semester/semester-list-item.component.ts b/src/app/modules/data/types/semester/semester-list-item.component.ts index 2fa5c400..86634cd3 100644 --- a/src/app/modules/data/types/semester/semester-list-item.component.ts +++ b/src/app/modules/data/types/semester/semester-list-item.component.ts @@ -16,14 +16,23 @@ import {Component, Input} from '@angular/core'; import {SCSemester} from '@openstapps/core'; import {DataListItem} from '../../list/data-list-item.component'; +/** + * TODO + */ @Component({ selector: 'stapps-semester-list-item', templateUrl: 'semester-list-item.html', }) - export class SemesterListItem extends DataListItem { + /** + * TODO + */ @Input() item: SCSemester; + /** + * TODO + */ + // tslint:disable-next-line:prefer-function-over-method ngOnInit() { // TODO: translation } diff --git a/src/app/modules/data/types/video/video-detail-content.component.ts b/src/app/modules/data/types/video/video-detail-content.component.ts index 6145f6df..0e260c67 100644 --- a/src/app/modules/data/types/video/video-detail-content.component.ts +++ b/src/app/modules/data/types/video/video-detail-content.component.ts @@ -16,16 +16,35 @@ import {Component, Input} from '@angular/core'; import {SCThing, SCTranslations, SCVideo} from '@openstapps/core'; import {SCThingTranslator} from '@openstapps/core'; +/** + * TODO + */ @Component({ selector: 'stapps-video-detail-content', templateUrl: 'video-detail-content.html', }) export class VideoDetailContentComponent { + /** + * TODO + */ @Input() item: SCVideo; + /** + * TODO + */ @Input() language: keyof SCTranslations; + /** + * TODO + */ objectKeys = Object.keys; + /** + * TODO + */ translator: SCThingTranslator; + + /** + * TODO + */ constructor() { - this.translator = new SCThingTranslator(this.language, 'de'); + this.translator = new SCThingTranslator(this.language); } } diff --git a/src/app/modules/data/types/video/video-list-item.component.ts b/src/app/modules/data/types/video/video-list-item.component.ts index 524f34fb..270bfbe9 100644 --- a/src/app/modules/data/types/video/video-list-item.component.ts +++ b/src/app/modules/data/types/video/video-list-item.component.ts @@ -16,14 +16,23 @@ import {Component, Input} from '@angular/core'; import {SCVideo} from '@openstapps/core'; import {DataListItem} from '../../list/data-list-item.component'; +/** + * TODO + */ @Component({ selector: 'stapps-video-list-item', templateUrl: 'video-list-item.html', }) - export class VideoListItem extends DataListItem { + /** + * TODO + */ @Input() item: SCVideo; + /** + * TODO + */ + // tslint:disable-next-line:prefer-function-over-method ngOnInit() { // TODO: translation } diff --git a/src/app/modules/menu/menu.module.ts b/src/app/modules/menu/menu.module.ts index 7ca94e7e..65c39a3c 100644 --- a/src/app/modules/menu/menu.module.ts +++ b/src/app/modules/menu/menu.module.ts @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 StApps + * 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. @@ -18,20 +18,23 @@ import {RouterModule} from '@angular/router'; import {IonicModule} from '@ionic/angular'; import {NavigationComponent} from './navigation/navigation.component'; +/** + * TODO + */ @NgModule({ declarations: [ NavigationComponent, ], entryComponents: [ - NavigationComponent + NavigationComponent, ], exports: [ - NavigationComponent + NavigationComponent, ], imports: [ IonicModule.forRoot(), CommonModule, - RouterModule - ] + RouterModule, + ], }) export class MenuModule {} diff --git a/src/app/modules/menu/navigation/navigation.component.ts b/src/app/modules/menu/navigation/navigation.component.ts index d75310ca..a262cd6e 100644 --- a/src/app/modules/menu/navigation/navigation.component.ts +++ b/src/app/modules/menu/navigation/navigation.component.ts @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 StApps + * 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. @@ -26,6 +26,9 @@ import {Component} from '@angular/core'; templateUrl: 'navigation.html', }) export class NavigationComponent { + /** + * TODO + */ public pages = [ {title: 'Search', url: '/search', icon: 'search'}, {title: 'Settings', url: '/settings', icon: 'settings'}, @@ -35,6 +38,10 @@ export class NavigationComponent { // Nothing yet. } + /** + * TODO + */ + // tslint:disable-next-line:prefer-function-over-method ionViewDidLoad() { // console.log('ionViewDidLoad MenuPage'); } diff --git a/src/app/modules/settings/item/settings-item.component.ts b/src/app/modules/settings/item/settings-item.component.ts index a3d5fad9..fbdcc369 100644 --- a/src/app/modules/settings/item/settings-item.component.ts +++ b/src/app/modules/settings/item/settings-item.component.ts @@ -17,34 +17,56 @@ import {AlertController} from '@ionic/angular'; import {LangChangeEvent, TranslateService} from '@ngx-translate/core'; import { SCSetting, + SCSettingValue, + SCSettingValues, SCThingTranslator, SCTranslations, } from '@openstapps/core'; -import {Logger} from '@openstapps/logger'; import {SettingsProvider} from '../settings.provider'; +/** + * TODO + */ @Component({ selector: 'stapps-settings-item', templateUrl: 'settings-item.html', }) export class SettingsItemComponent { + /** + * TODO + */ isVisible = true; - // limit to languages that are available in StApps Core + /** + * TODO + * + * limit to languages that are available in StApps Core + */ language: keyof SCTranslations; - logger = new Logger(); + /** + * TODO + */ @Input() setting: SCSetting; + /** + * TODO + */ translator: SCThingTranslator; - constructor(private alertCtrl: AlertController, - private translateService: TranslateService, - private settingsProvider: SettingsProvider) { + /** + * + * @param alertCtrl TODO + * @param translateService TODO + * @param settingsProvider TODO + */ + constructor(private readonly alertCtrl: AlertController, + private readonly translateService: TranslateService, + private readonly settingsProvider: SettingsProvider) { this.language = translateService.currentLang as keyof SCTranslations; - this.translator = new SCThingTranslator(this.language, 'de'); + this.translator = new SCThingTranslator(this.language); translateService.onLangChange.subscribe((event: LangChangeEvent) => { this.isVisible = false; this.language = event.lang as keyof SCTranslations; - this.translator = new SCThingTranslator(this.language, 'de'); + this.translator = new SCThingTranslator(this.language); // TODO: Issue #53 check workaround for selected 'select option' not updating translation setTimeout(() => this.isVisible = true); }); @@ -58,7 +80,7 @@ export class SettingsItemComponent { const permissionGranted = await this.settingsProvider.checkGeoLocationPermission(); if (!permissionGranted) { // revert setting value - this.setting.input.value = false; + this.setting.value = false; await this.presentGeoLocationAlert(); } } @@ -67,8 +89,10 @@ export class SettingsItemComponent { * Shows alert with error message on denied user permission or disabled location services */ private async presentGeoLocationAlert() { - const title = await this.translateService.get('settings.geoLocation.permission_denied_title').toPromise(); - const message = await this.translateService.get('settings.geoLocation.permission_denied_message').toPromise(); + const title = await this.translateService.get('settings.geoLocation.permission_denied_title') + .toPromise(); + const message = await this.translateService.get('settings.geoLocation.permission_denied_message') + .toPromise(); await this.presentAlert(title, message); } @@ -91,29 +115,34 @@ export class SettingsItemComponent { * Handles value changes of the setting */ async settingChanged(): Promise { - if (typeof this.setting.input.value !== 'undefined' - && SettingsProvider.validateValue(this.setting, this.setting.input.value)) { + if (typeof this.setting.value !== 'undefined' + && SettingsProvider.validateValue(this.setting, this.setting.value)) { // handle general settings, with special actions switch (this.setting.name) { case 'language': - this.translateService.use(this.setting.input.value.toString()); + this.translateService.use(this.setting.value.toString()); break; case 'geoLocation': - if (this.setting.input.value) { + if (this.setting.value) { await this.checkGeoLocationPermission(); } break; default: } await this.settingsProvider - .setSettingValue(this.setting.categories[0], this.setting.name, this.setting.input.value); + .setSettingValue(this.setting.categories[0], this.setting.name, this.setting.value); } else { // reset setting - this.setting.input.value = - await this.settingsProvider.getValue(this.setting.categories[0], this.setting.name); + this.setting.value = + await this.settingsProvider + .getValue(this.setting.categories[0], this.setting.name) as (SCSettingValue | SCSettingValues); } } + /** + * TODO + */ + // tslint:disable-next-line:prefer-function-over-method typeOf(val: any) { return typeof (val); } diff --git a/src/app/modules/settings/item/settings-item.html b/src/app/modules/settings/item/settings-item.html index 66d57d06..774287f7 100644 --- a/src/app/modules/settings/item/settings-item.html +++ b/src/app/modules/settings/item/settings-item.html @@ -5,27 +5,27 @@ {{ translator.translate(setting).description() }} -
+
- + - + - + - - - + + +
{{ val }}
{{ val }}
@@ -34,8 +34,8 @@ - - + +
{{ val }}
{{ val }}
diff --git a/src/app/modules/settings/page/settings-page.component.ts b/src/app/modules/settings/page/settings-page.component.ts index 2bd4d120..2c7dbe8a 100644 --- a/src/app/modules/settings/page/settings-page.component.ts +++ b/src/app/modules/settings/page/settings-page.component.ts @@ -18,29 +18,58 @@ import {LangChangeEvent, TranslateService} from '@ngx-translate/core'; import {SCSettingMeta, SCThingTranslator, SCTranslations} from '@openstapps/core'; import {SettingsCache, SettingsProvider} from '../settings.provider'; + /** + * TODO + */ @Component({ selector: 'stapps-settings-page', templateUrl: 'settings-page.html', }) export class SettingsPageComponent { + /** + * Order of the categories + */ categoriesOrder: string[]; - // limit to languages that are available in StApps Core + /** + * Possible languages to be used for translation + * + * limit to languages that are available in StApps Core + */ language: keyof SCTranslations; + /** + * Meta information about settings + */ meta = SCSettingMeta; + /** + * TODO + */ objectKeys = Object.keys; + /** + * TODO + */ settingsCache: SettingsCache; + /** + * TODO + */ translator: SCThingTranslator; - constructor(private alertController: AlertController, - private settingsProvider: SettingsProvider, - private toastController: ToastController, - private translateService: TranslateService) { + /** + * + * @param alertController TODO + * @param settingsProvider TODO + * @param toastController TODO + * @param translateService TODO + */ + constructor(private readonly alertController: AlertController, + private readonly settingsProvider: SettingsProvider, + private readonly toastController: ToastController, + private readonly translateService: TranslateService) { this.language = translateService.currentLang as keyof SCTranslations; - this.translator = new SCThingTranslator(this.language, 'de'); + this.translator = new SCThingTranslator(this.language); translateService.onLangChange.subscribe((event: LangChangeEvent) => { this.language = event.lang as keyof SCTranslations; - this.translator = new SCThingTranslator(this.language, 'de'); + this.translator = new SCThingTranslator(this.language); }); this.settingsCache = {}; this.categoriesOrder = settingsProvider.getCategoriesOrder(); @@ -66,6 +95,9 @@ export class SettingsPageComponent { this.settingsCache = await this.settingsProvider.getCache(); } + /** + * Component initialize method + */ async ngOnInit() { await this.loadSettings(); } @@ -74,10 +106,14 @@ export class SettingsPageComponent { * Presents an alert to the user to reset settings to default values */ async presentResetAlert() { - const cancelText = await this.translateService.get('settings.resetAlert.buttonCancel').toPromise(); - const yesText = await this.translateService.get('settings.resetAlert.buttonYes').toPromise(); - const title = await this.translateService.get('settings.resetAlert.title').toPromise(); - const message = await this.translateService.get('settings.resetAlert.message').toPromise(); + const cancelText = await this.translateService.get('settings.resetAlert.buttonCancel') + .toPromise(); + const yesText = await this.translateService.get('settings.resetAlert.buttonYes') + .toPromise(); + const title = await this.translateService.get('settings.resetAlert.title') + .toPromise(); + const message = await this.translateService.get('settings.resetAlert.message') + .toPromise(); const alert = await this.alertController.create({ buttons: [ diff --git a/src/app/modules/settings/page/settings-page.html b/src/app/modules/settings/page/settings-page.html index 86ab5d74..0d04b6cf 100644 --- a/src/app/modules/settings/page/settings-page.html +++ b/src/app/modules/settings/page/settings-page.html @@ -12,7 +12,7 @@
-
{{translator.translate(settingsCache[categoryKey].settings[objectKeys(settingsCache[categoryKey].settings)[0]]).categories()[0]}} +
{{ settingsCache[categoryKey].settings[objectKeys(settingsCache[categoryKey].settings)[0]].translations[language].categories[0]}}
diff --git a/src/app/modules/settings/settings.module.ts b/src/app/modules/settings/settings.module.ts index 05d08a1b..771cd19e 100644 --- a/src/app/modules/settings/settings.module.ts +++ b/src/app/modules/settings/settings.module.ts @@ -29,6 +29,9 @@ const settingsRoutes: Routes = [ {path: 'settings', component: SettingsPageComponent}, ]; +/** + * Settings Module + */ @NgModule({ declarations: [ SettingsPageComponent, diff --git a/src/app/modules/settings/settings.provider.spec.ts b/src/app/modules/settings/settings.provider.spec.ts index 24062704..fceaef29 100644 --- a/src/app/modules/settings/settings.provider.spec.ts +++ b/src/app/modules/settings/settings.provider.spec.ts @@ -13,7 +13,7 @@ * this program. If not, see . */ import {TestBed} from '@angular/core/testing'; -import {SCSetting, SCThingOriginType, SCThingType} from '@openstapps/core'; +import {SCSetting, SCThingOriginType, SCThingType, SCSettingInputType} from '@openstapps/core'; import {ConfigProvider} from '../config/config.provider'; import {StorageProvider} from '../storage/storage.provider'; import {SettingsProvider, SettingValuesContainer, STORAGE_KEY_SETTING_VALUES} from './settings.provider'; @@ -53,14 +53,14 @@ describe('SettingsProvider', () => { await settingsProvider.provideSetting(JSON.parse(JSON.stringify(CONFIG_SETTINGS_MOCK[0]))); const setting: SCSetting = await settingsProvider .getSetting(CONFIG_SETTINGS_MOCK[0].categories[0], CONFIG_SETTINGS_MOCK[0].name); - await expect(setting.input.value).toBeDefined(); + await expect(setting.value).toBeDefined(); }); it('should provide and get settings value', async () => { await settingsProvider.provideSetting(JSON.parse(JSON.stringify(CONFIG_SETTINGS_MOCK[0]))); const value = await settingsProvider .getValue(CONFIG_SETTINGS_MOCK[0].categories[0], CONFIG_SETTINGS_MOCK[0].name); - await expect(value).toEqual(CONFIG_SETTINGS_MOCK[0].input.defaultValue); + await expect(value).toEqual(CONFIG_SETTINGS_MOCK[0].defaultValue); }); it('should get persisted setting value', async () => { @@ -79,7 +79,7 @@ describe('SettingsProvider', () => { storageProviderSpy.get.and.returnValue(Promise.resolve([])); const value = await settingsProvider .getValue(CONFIG_SETTINGS_MOCK[3].categories[0], CONFIG_SETTINGS_MOCK[3].name); - await expect(value).toEqual(CONFIG_SETTINGS_MOCK[3].input.defaultValue); + await expect(value).toEqual(CONFIG_SETTINGS_MOCK[3].defaultValue); }); it('should keep persisted setting values from settings that are not contained in loaded config', async () => { @@ -108,10 +108,10 @@ describe('SettingsProvider', () => { const name = CONFIG_SETTINGS_MOCK[0].name; await settingsProvider.provideSetting(JSON.parse(JSON.stringify(CONFIG_SETTINGS_MOCK[0]))); const settings = await settingsProvider.getCache(); - settings[category].settings[name].input.value = 'testValue'; + settings[category].settings[name].value = 'testValue'; // cached setting value should still be defaultValue await expect((await settingsProvider.getValue(category, name))) - .toEqual(CONFIG_SETTINGS_MOCK[0].input.defaultValue); + .toEqual(CONFIG_SETTINGS_MOCK[0].defaultValue); }); it('should call storage put on setSettingValue', async () => { @@ -134,7 +134,7 @@ describe('SettingsProvider', () => { await settingsProvider.resetDefault(); const value = await settingsProvider .getValue(CONFIG_SETTINGS_MOCK[0].categories[0], CONFIG_SETTINGS_MOCK[0].name); - await expect(value).toEqual(CONFIG_SETTINGS_MOCK[0].input.defaultValue); + await expect(value).toEqual(CONFIG_SETTINGS_MOCK[0].defaultValue); }); it('should validate wrong values for inputType text', async () => { @@ -172,7 +172,7 @@ describe('SettingsProvider', () => { await testValue(CONFIG_SETTINGS_MOCK[6], ''); await testValue(CONFIG_SETTINGS_MOCK[6], 123456); await testValue(CONFIG_SETTINGS_MOCK[6], false); - await testValue(CONFIG_SETTINGS_MOCK[6], [1, 2, 3, 4]); + await testValue(CONFIG_SETTINGS_MOCK[6], [1, 9]); }); async function testValue(setting: SCSetting, value: any) { @@ -192,10 +192,8 @@ describe('SettingsProvider', () => { const CONFIG_SETTINGS_MOCK: SCSetting[] = [ { categories: ['credentials'], - input: { - defaultValue: '', - inputType: 'text', - }, + defaultValue: '', + inputType: SCSettingInputType.Text, name: 'username', order: 0, origin: { @@ -219,10 +217,8 @@ describe('SettingsProvider', () => { { categories: ['credentials'], description: '', - input: { - defaultValue: '', - inputType: 'password', - }, + defaultValue: '', + inputType: SCSettingInputType.Password, name: 'password', order: 1, origin: { @@ -246,10 +242,8 @@ describe('SettingsProvider', () => { { categories: ['profile'], description: '', - input: { - defaultValue: 0, - inputType: 'number', - }, + defaultValue: 0, + inputType: SCSettingInputType.Number, name: 'age', order: 0, origin: { @@ -273,11 +267,8 @@ describe('SettingsProvider', () => { { categories: ['profile'], description: '', - input: { - defaultValue: 'student', - inputType: 'singleChoice', - values: ['student', 'employee', 'guest'], - }, + defaultValue: 'student', + inputType: SCSettingInputType.SingleChoice, name: 'group', order: 1, origin: { @@ -301,15 +292,13 @@ describe('SettingsProvider', () => { }, type: SCThingType.Setting, uid: '', + values: ['student', 'employee', 'guest'], }, { categories: ['profile'], description: '', - input: { - defaultValue: 'en', - inputType: 'singleChoice', - values: ['en', 'de'], - }, + defaultValue: 'en', + inputType: SCSettingInputType.SingleChoice, name: 'language', order: 0, origin: { @@ -331,15 +320,13 @@ describe('SettingsProvider', () => { }, type: SCThingType.Setting, uid: '', + values: ['en', 'de'], }, { categories: ['privacy'], description: '', - input: { - defaultValue: false, - inputType: 'singleChoice', - values: [true, false], - }, + defaultValue: false, + inputType: SCSettingInputType.SingleChoice, name: 'geoLocation', order: 0, origin: { @@ -363,15 +350,13 @@ describe('SettingsProvider', () => { }, type: SCThingType.Setting, uid: '', + values: [true, false], }, { categories: ['others'], description: '', - input: { - defaultValue: [], - inputType: 'multipleChoice', - values: [1, 2, 3, 4, 5, 6, 7, 8], - }, + defaultValue: [], + inputType: SCSettingInputType.MultipleChoice, name: 'numbers', order: 0, origin: { @@ -393,6 +378,7 @@ describe('SettingsProvider', () => { }, type: SCThingType.Setting, uid: '', + values: [1, 2, 3, 4, 5, 6, 7, 8], }, ]; }); diff --git a/src/app/modules/settings/settings.provider.ts b/src/app/modules/settings/settings.provider.ts index 9b325333..894218b1 100644 --- a/src/app/modules/settings/settings.provider.ts +++ b/src/app/modules/settings/settings.provider.ts @@ -16,25 +16,29 @@ import {Injectable} from '@angular/core'; import {Geolocation} from '@ionic-native/geolocation/ngx'; import { SCSetting, - SCSettingMultipleChoice, - SCSettingSingleChoice, SCSettingValue, + SCSettingValues, } from '@openstapps/core'; -import {Logger} from '@openstapps/logger'; import * as deepMerge from 'deepmerge'; import {ConfigProvider} from '../config/config.provider'; import {StorageProvider} from '../storage/storage.provider'; export const STORAGE_KEY_SETTINGS = 'settings'; export const STORAGE_KEY_SETTINGS_SEPARATOR = '.'; -export const STORAGE_KEY_SETTING_VALUES = STORAGE_KEY_SETTINGS + STORAGE_KEY_SETTINGS_SEPARATOR + 'values'; +export const STORAGE_KEY_SETTING_VALUES = `${STORAGE_KEY_SETTINGS}${STORAGE_KEY_SETTINGS_SEPARATOR}values`; /** * Category structure of settings cache */ export interface CategoryWithSettings { + /** + * Category name + */ category: string; - settings: { [key: string]: SCSetting }; + /** + * Settings that belong in this category + */ + settings: { [key: string]: SCSetting; }; } /** @@ -60,36 +64,61 @@ export interface SettingValueContainer { /** * Provider for app settings + * */ @Injectable() export class SettingsProvider { + /** + * Order of the setting categories + */ categoriesOrder: string[]; + /** + * Is provider initialized + */ initialized = false; - logger = new Logger(); + /** + * Cache for the imported settings + */ settingsCache: SettingsCache; /** * Return true if all given values are valid to possible values in given settingInput - * @param settingInput - * @param values + * @param possibleValues Possible values + * @param enteredValues Entered value */ - public static checkMultipleChoiceValue(settingInput: SCSettingMultipleChoice, values: SCSettingValue[]): boolean { - for (const value of values) { - if (!settingInput.values.includes(value)) { + public static checkMultipleChoiceValue( + possibleValues: SCSettingValues | undefined, + enteredValues: SCSettingValues, + ): boolean { + if ( typeof possibleValues === 'undefined' ) { + return false; + } + + for (const value of enteredValues) { + if (!possibleValues.includes(value)) { return false; } } + return true; } /** * Returns true if given value is valid to possible values in given settingInput - * @param settingInput - * @param value + * @param possibleValues Possible values + * @param enteredValue Entered value */ - public static checkSingleChoiceValue(settingInput: SCSettingSingleChoice, value: SCSettingValue): boolean { - return settingInput.values !== undefined - && settingInput.values.includes(value); + public static checkSingleChoiceValue( + possibleValues: SCSettingValues | undefined, + enteredValue: SCSettingValue, + ): boolean { + if ( typeof possibleValues === 'undefined' ) { + return false; + } + + return possibleValues !== undefined + && (Array.isArray(possibleValues) + && possibleValues.includes(enteredValue)); } /** @@ -97,19 +126,19 @@ export class SettingsProvider { * @param setting setting to check value against * @param value value to validate */ - public static validateValue(setting: SCSetting, value: any): boolean { - let isValueValid: boolean = false; - switch (setting.input.inputType) { + public static validateValue(setting: SCSetting, value: SCSettingValue | SCSettingValues): boolean { + let isValueValid = false; + switch (setting.inputType) { case 'number': if (typeof value === 'number') { isValueValid = true; } break; - case 'multipleChoice': - if (!value.isArray) { + case 'multiple choice': + if (!Array.isArray(value)) { isValueValid = false; } else { - isValueValid = SettingsProvider.checkMultipleChoiceValue(setting.input, value); + isValueValid = SettingsProvider.checkMultipleChoiceValue(setting.values, value); } break; case 'password': @@ -118,32 +147,43 @@ export class SettingsProvider { isValueValid = true; } break; - case 'singleChoice': - isValueValid = SettingsProvider.checkSingleChoiceValue(setting.input, value); + case 'single choice': + if (Array.isArray(value)) { + isValueValid = false; + } else { + isValueValid = SettingsProvider.checkSingleChoiceValue(setting.values, value); + } break; default: } + return isValueValid; } - constructor(private storage: StorageProvider, - private configProvider: ConfigProvider, - private geoLocation: Geolocation) { + /** + * + * @param storage TODO + * @param configProvider TODO + * @param geoLocation TODO + */ + constructor(private readonly storage: StorageProvider, + private readonly configProvider: ConfigProvider, + private readonly geoLocation: Geolocation) { this.categoriesOrder = []; this.settingsCache = {}; } /** * Add an Setting to the Cache if not exist and set undefined value to defaultValue - * @param setting + * @param setting Setting with categories, defautlValue, name, input type and valid values */ private async addSetting(setting: SCSetting): Promise { if (!this.categoryExists(setting.categories[0])) { await this.provideCategory(setting.categories[0]); } if (!this.settingExists(setting.categories[0], setting.name)) { - if (setting.input.value === undefined) { - setting.input.value = setting.input.defaultValue; + if (setting.value === undefined) { + setting.value = setting.defaultValue; } this.settingsCache[setting.categories[0]].settings[setting.name] = setting; } @@ -162,9 +202,10 @@ export class SettingsProvider { settingValuesContainer[categoryKey] = {}; } settingValuesContainer[categoryKey][settingKey] = - this.settingsCache[categoryKey].settings[settingKey].input.value; + this.settingsCache[categoryKey].settings[settingKey].value; } } + return settingValuesContainer; } @@ -196,11 +237,11 @@ export class SettingsProvider { // if saved setting value exists set it, otherwise set to default value if (typeof valuesContainer[categoryKey] !== 'undefined' && typeof valuesContainer[categoryKey][settingKey] !== 'undefined') { - this.settingsCache[categoryKey].settings[settingKey].input.value = + this.settingsCache[categoryKey].settings[settingKey].value = valuesContainer[categoryKey][settingKey]; } else { - this.settingsCache[categoryKey].settings[settingKey].input.value = - this.settingsCache[categoryKey].settings[settingKey].input.defaultValue; + this.settingsCache[categoryKey].settings[settingKey].value = + this.settingsCache[categoryKey].settings[settingKey].defaultValue; } } } @@ -228,7 +269,7 @@ export class SettingsProvider { /** * Returns true if category exists - * @param category + * @param category Category key name */ public categoryExists(category: string): boolean { return this.settingsCache[category] !== undefined; @@ -256,6 +297,7 @@ export class SettingsProvider { } } } + return true; } @@ -264,6 +306,7 @@ export class SettingsProvider { */ public async getCache(): Promise { await this.init(); + return JSON.parse(JSON.stringify(this.settingsCache)); } @@ -281,14 +324,13 @@ export class SettingsProvider { * * @throws Exception if setting is not provided */ - public async getSetting(category: string, name: string): Promise { + public async getSetting(category: string, name: string): Promise { await this.init(); if (this.settingExists(category, name)) { // return a copy of the settings return JSON.parse(JSON.stringify(this.settingsCache[category].settings[name])); - } else { - throw new Error(`Setting "${name}" not provided`); } + throw new Error(`Setting "${name}" not provided`); } /** @@ -302,10 +344,9 @@ export class SettingsProvider { await this.init(); if (this.settingExists(category, name)) { // return a copy of the settings value - return JSON.parse(JSON.stringify(this.settingsCache[category].settings[name].input.value)); - } else { - throw new Error(`Setting "${name}" not provided`); + return JSON.parse(JSON.stringify(this.settingsCache[category].settings[name].value)); } + throw new Error(`Setting "${name}" not provided`); } /** @@ -340,7 +381,7 @@ export class SettingsProvider { async resetDefault(): Promise { for (const catKey of Object.keys(this.settingsCache)) { for (const settingKey of Object.keys(this.settingsCache[catKey].settings)) { - const settingInput = this.settingsCache[catKey].settings[settingKey].input; + const settingInput = this.settingsCache[catKey].settings[settingKey]; settingInput.value = settingInput.defaultValue; } } @@ -373,24 +414,24 @@ export class SettingsProvider { /** * Sets a valid value of a setting and persists changes in storage - * @param category - * @param name - * @param value + * @param category Category key name + * @param name Setting key name + * @param value Value to be set * * @throws Exception if setting is not provided or value not valid to the settings inputType */ public async setSettingValue(category: string, name: string, - value: any): Promise { + value: SCSettingValue | SCSettingValues): Promise { await this.init(); if (this.settingExists(category, name)) { const setting: SCSetting = this.settingsCache[category].settings[name]; const isValueValid = SettingsProvider.validateValue(setting, value); if (isValueValid) { - this.settingsCache[category].settings[name].input.value = value; + this.settingsCache[category].settings[name].value = value; await this.saveSettingValues(); } else { throw new Error(`Value "${value}" of type - ${typeof value} is not valid for ${setting.input.inputType}`); + ${typeof value} is not valid for ${setting.inputType}`); } } else { throw new Error(`setting ${name} is not provided`); @@ -399,8 +440,8 @@ export class SettingsProvider { /** * Returns true if setting in category exists - * @param category - * @param setting + * @param category Category key name + * @param setting Setting key name */ public settingExists(category: string, setting: string): boolean { return this.categoryExists(category) && this.settingsCache[category].settings[setting] !== undefined; diff --git a/src/app/modules/storage/storage.module.ts b/src/app/modules/storage/storage.module.ts index 6edb2476..ccf6ce40 100644 --- a/src/app/modules/storage/storage.module.ts +++ b/src/app/modules/storage/storage.module.ts @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 StApps + * 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. @@ -12,16 +12,19 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ -import { NgModule } from '@angular/core'; -import { IonicStorageModule } from '@ionic/storage'; -import { StorageProvider } from './storage.provider'; +import {NgModule} from '@angular/core'; +import {IonicStorageModule} from '@ionic/storage'; +import {StorageProvider} from './storage.provider'; +/** + * Angular storage provider module + */ @NgModule({ imports: [ - IonicStorageModule.forRoot() + IonicStorageModule.forRoot(), ], providers: [ - StorageProvider - ] + StorageProvider, + ], }) export class StorageModule {} diff --git a/src/app/modules/storage/storage.provider.ts b/src/app/modules/storage/storage.provider.ts index 536c91e2..d252ba1e 100644 --- a/src/app/modules/storage/storage.provider.ts +++ b/src/app/modules/storage/storage.provider.ts @@ -20,24 +20,29 @@ import {Storage} from '@ionic/storage'; */ @Injectable() export class StorageProvider { - constructor(private storage: Storage) { - } - /** - * Initializes the storage (waits until it's ready) + * + * @param storage TODO */ - async init(): Promise { - return this.storage.ready(); + constructor(private readonly storage: Storage) { } /** - * Puts a value of type T into the storage using provided key + * Deletes storage entries using keys used to save them * - * @param key Unique indentifier - * @param value Resource to store under the key + * @param keys Unique identifiers of the resources for deletion */ - async put(key: string, value: T): Promise { - return this.storage.set(key, value); + async delete(...keys: string[]): Promise { + keys.forEach(async (key) => { + await this.storage.remove(key); + }); + } + + /** + * Deletes all the entries in the storage (empty the storage) + */ + async deleteAll(): Promise { + return this.storage.clear(); } /** @@ -50,68 +55,23 @@ export class StorageProvider { if (!entry) { throw new Error('Value not found.'); } + return entry; } + // tslint:disable:no-any /** - * Gets values from the storage using the provided pattern - * - * @param pattern Regular expression or text to test existing storage keys with + * Retrieves all the storage entries */ - async search(pattern: RegExp | string): Promise> { + async getAll(): Promise> { const map: Map = new Map(); - const check = (input: RegExp | string) => { - if (input instanceof RegExp) { - return (p: any, k: string): boolean => { - return p.test(k); - }; - } else { - return (p: any, k: string): boolean => { - return k.includes(p); - }; - } - }; - const checkIt = check(pattern); await this.storage.forEach((value, key) => { - if (checkIt(pattern, key)) { - map.set(key, value); - } + map.set(key, value); }); + return map; } - /** - * Deletes storage entries using keys used to save them - * - * @param keys Unique identifiers of the resources for deletion - */ - async delete(...keys: string[]): Promise { - await keys.forEach((key) => { - this.storage.remove(key); - }); - } - - /** - * Deletes all the entries in the storage (empty the storage) - */ - async deleteAll(): Promise { - return this.storage.clear(); - } - - /** - * Saves multiple entries into the storage - * - * @param entries Resources to be put into the storage - */ - async putMultiple(entries: Map): Promise> { - const puts: Array> = []; - entries.forEach(async (value, key) => { - puts.push(this.put(key, value)); - }); - await Promise.all(puts); - return entries; - } - /** * Retrieves multiple entries from the storage using their keys * @@ -127,34 +87,10 @@ export class StorageProvider { gets.push(getToMap(key)); }); await Promise.all(gets); + return map; } - /** - * Retrieves all the storage entries - */ - async getAll(): Promise> { - const map: Map = new Map(); - await this.storage.forEach((value, key) => { - map.set(key, value); - }); - return map; - } - - /** - * Provides a number of entries in the storage (number of keys) - */ - async length(): Promise { - return this.storage.length(); - } - - /** - * Provides information if storage is empty or not - */ - async isEmpty(): Promise { - return (await this.storage.length()) === 0; - } - /** * Provides information if storage has an entry with the given key * @@ -163,4 +99,78 @@ export class StorageProvider { async has(key: string): Promise { return (await this.storage.keys()).includes(key); } + + /** + * Initializes the storage (waits until it's ready) + */ + async init(): Promise { + return this.storage.ready(); + } + + /** + * Provides information if storage is empty or not + */ + async isEmpty(): Promise { + return (await this.storage.length()) === 0; + } + + /** + * Provides a number of entries in the storage (number of keys) + */ + async length(): Promise { + return this.storage.length(); + } + + /** + * Puts a value of type T into the storage using provided key + * + * @param key Unique indentifier + * @param value Resource to store under the key + */ + async put(key: string, value: T): Promise { + return this.storage.set(key, value); + } + + /** + * Saves multiple entries into the storage + * + * @param entries Resources to be put into the storage + */ + async putMultiple(entries: Map): Promise> { + const puts: Array> = []; + entries.forEach(async (value, key) => { + puts.push(this.put(key, value)); + }); + await Promise.all(puts); + + return entries; + } + + /** + * Gets values from the storage using the provided pattern + * + * @param pattern Regular expression or text to test existing storage keys with + */ + async search(pattern: RegExp | string): Promise> { + const map: Map = new Map(); + const check = (input: RegExp | string) => { + if (input instanceof RegExp) { + return (p: any, k: string): boolean => { + return p.test(k); + }; + } + + return (p: any, k: string): boolean => { + return k.includes(p); + }; + }; + const checkIt = check(pattern); + await this.storage.forEach((value, key) => { + if (checkIt(pattern, key)) { + map.set(key, value); + } + }); + + return map; + } } diff --git a/src/main.ts b/src/main.ts index 336fbcc5..94a790da 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 StApps + * 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. @@ -12,15 +12,16 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ -import { enableProdMode } from '@angular/core'; -import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; - -import { AppModule } from './app/app.module'; -import { environment } from './environments/environment'; +import {enableProdMode} from '@angular/core'; +import {platformBrowserDynamic} from '@angular/platform-browser-dynamic'; +import {Logger} from '@openstapps/logger'; +import {AppModule} from './app/app.module'; +import {environment} from './environments/environment'; if (environment.production) { enableProdMode(); } -platformBrowserDynamic().bootstrapModule(AppModule) - .catch(err => console.log(err)); +platformBrowserDynamic() + .bootstrapModule(AppModule) + .catch(async (err) => await Logger.error(err)); diff --git a/src/polyfills.ts b/src/polyfills.ts index 00707ef2..c5b6dbf1 100644 --- a/src/polyfills.ts +++ b/src/polyfills.ts @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 StApps + * 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. @@ -32,7 +32,9 @@ * BROWSER POLYFILLS */ -/** IE9, IE10 and IE11 requires all of the following polyfills. **/ +/* + * IE9, IE10 and IE11 requires all of the following polyfills. + */ // import 'core-js/es6/symbol'; // import 'core-js/es6/object'; // import 'core-js/es6/function'; @@ -54,27 +56,23 @@ /** IE10 and IE11 requires the following for the Reflect API. */ // import 'core-js/es6/reflect'; - -/** Evergreen browsers require these. **/ +/* + * Evergreen browsers require these. + */ // Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove. import 'core-js/es7/reflect'; - /** * Required to support Web Animations `@angular/platform-browser/animations`. * Needed for: All but Chrome, Firefox and Opera. http://caniuse.com/#feat=web-animation - **/ + */ // import 'web-animations-js'; // Run `npm install --save web-animations-js`. - - /*************************************************************************************************** * Zone JS is required by Angular itself. */ import 'zone.js/dist/zone'; // Included with Angular CLI. - - /*************************************************************************************************** * APPLICATION IMPORTS */ diff --git a/src/test.ts b/src/test.ts index 3a7e5203..18cc8c37 100644 --- a/src/test.ts +++ b/src/test.ts @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 StApps + * 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. @@ -14,21 +14,24 @@ */ // This file is required by karma.conf.js and loads recursively all the .spec and framework files -import { getTestBed } from '@angular/core/testing'; +import {getTestBed} from '@angular/core/testing'; import { BrowserDynamicTestingModule, - platformBrowserDynamicTesting + platformBrowserDynamicTesting, } from '@angular/platform-browser-dynamic/testing'; import 'zone.js/dist/zone-testing'; +// tslint:disable-next-line:no-any declare const require: any; // First, initialize the Angular testing environment. -getTestBed().initTestEnvironment( - BrowserDynamicTestingModule, - platformBrowserDynamicTesting() -); +getTestBed() + .initTestEnvironment( + BrowserDynamicTestingModule, + platformBrowserDynamicTesting(), + ); // Then we find all the tests. const context = require.context('./', true, /\.spec\.ts$/); // And load the modules. -context.keys().map(context); +context.keys() + .map(context);