diff --git a/package-lock.json b/package-lock.json index d0279a2f..4056a837 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3061,6 +3061,7 @@ "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", "dev": true, + "optional": true, "requires": { "delegates": "^1.0.0", "readable-stream": "^2.0.6" @@ -4570,7 +4571,8 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true + "dev": true, + "optional": true }, "constants-browserify": { "version": "1.0.0", @@ -5196,7 +5198,8 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", - "dev": true + "dev": true, + "optional": true }, "depd": { "version": "1.1.2", @@ -6948,6 +6951,7 @@ "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", "dev": true, + "optional": true, "requires": { "graceful-fs": "^4.1.2", "inherits": "~2.0.0", @@ -6976,6 +6980,7 @@ "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", "dev": true, + "optional": true, "requires": { "aproba": "^1.0.3", "console-control-strings": "^1.0.0", @@ -6991,13 +6996,15 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true + "dev": true, + "optional": true }, "is-fullwidth-code-point": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -7007,6 +7014,7 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -7018,6 +7026,7 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -7050,7 +7059,8 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", - "dev": true + "dev": true, + "optional": true }, "get-stream": { "version": "3.0.0", @@ -7249,7 +7259,8 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", - "dev": true + "dev": true, + "optional": true }, "has-value": { "version": "1.0.0", @@ -8095,7 +8106,8 @@ "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", - "dev": true + "dev": true, + "optional": true }, "is-windows": { "version": "1.0.2", @@ -8836,6 +8848,7 @@ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", "dev": true, + "optional": true, "requires": { "graceful-fs": "^4.1.2", "parse-json": "^2.2.0", @@ -8848,7 +8861,8 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true + "dev": true, + "optional": true } } }, @@ -9166,7 +9180,8 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", - "dev": true + "dev": true, + "optional": true }, "map-stream": { "version": "0.1.0", @@ -9894,6 +9909,7 @@ "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", "dev": true, + "optional": true, "requires": { "are-we-there-yet": "~1.1.2", "console-control-strings": "~1.1.0", @@ -11201,7 +11217,8 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true + "dev": true, + "optional": true } } }, @@ -11210,6 +11227,7 @@ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", "dev": true, + "optional": true, "requires": { "load-json-file": "^1.0.0", "normalize-package-data": "^2.3.2", @@ -11221,6 +11239,7 @@ "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", "dev": true, + "optional": true, "requires": { "graceful-fs": "^4.1.2", "pify": "^2.0.0", @@ -11240,6 +11259,7 @@ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", "dev": true, + "optional": true, "requires": { "find-up": "^1.0.0", "read-pkg": "^1.0.0" @@ -11250,6 +11270,7 @@ "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", "dev": true, + "optional": true, "requires": { "path-exists": "^2.0.0", "pinkie-promise": "^2.0.0" @@ -11260,6 +11281,7 @@ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", "dev": true, + "optional": true, "requires": { "pinkie-promise": "^2.0.0" } @@ -12697,6 +12719,7 @@ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", "dev": true, + "optional": true, "requires": { "is-utf8": "^0.2.0" } @@ -14396,6 +14419,7 @@ "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", "dev": true, + "optional": true, "requires": { "string-width": "^1.0.2 || 2" } diff --git a/src/app/_helpers/data/sampleConfiguration.ts b/src/app/_helpers/data/sampleConfiguration.ts new file mode 100644 index 00000000..c32bd28c --- /dev/null +++ b/src/app/_helpers/data/sampleConfiguration.ts @@ -0,0 +1,74 @@ +/* + * 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 . + */ +import {SCBackendAggregationConfiguration, SCThingType} from '@openstapps/core'; + +// provides sample aggregations to be used in tests or backendless development +export const sampleAggregations: SCBackendAggregationConfiguration[] = [ + { + fieldName: 'categories', + onlyOnTypes: [ + SCThingType.AcademicEvent, + SCThingType.Article, + SCThingType.Building, + SCThingType.Catalog, + SCThingType.Dish, + SCThingType.PointOfInterest, + SCThingType.Room, + ], + }, + { + fieldName: 'inPlace.name', + onlyOnTypes: [ + SCThingType.DateSeries, + SCThingType.Dish, + SCThingType.Floor, + SCThingType.Organization, + SCThingType.PointOfInterest, + SCThingType.Room, + SCThingType.Ticket, + ], + }, + { + fieldName: 'academicTerms.acronym', + onlyOnTypes: [ + SCThingType.AcademicEvent, + SCThingType.SportCourse, + ], + }, + { + fieldName: 'academicTerm.acronym', + onlyOnTypes: [ + SCThingType.Catalog, + ], + }, + { + fieldName: 'majors', + onlyOnTypes: [ + SCThingType.AcademicEvent, + ], + }, + { + fieldName: 'keywords', + onlyOnTypes: [ + SCThingType.Article, + SCThingType.Book, + SCThingType.Message, + SCThingType.Video, + ], + }, + { + fieldName: 'type', + }, +]; diff --git a/src/app/_helpers/data/sampleThings.ts b/src/app/_helpers/data/sampleThings.ts new file mode 100644 index 00000000..7a000c97 --- /dev/null +++ b/src/app/_helpers/data/sampleThings.ts @@ -0,0 +1,370 @@ +/* + * 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 . + */ +import {SCAcademicEvent, SCArticle, SCBook, SCBuilding, SCCatalog, + SCDateSeries, SCDish, SCFavorite, SCMessage, SCPerson, SCRoom, + SCThing, SCThingOriginType, SCThingType, SCToDo, SCToDoPriority} from '@openstapps/core'; + +const sampleMessages: SCMessage[] = [ + { + audiences: ['students'], + message: 'Foo Message Text', + name: 'Foo Message', + origin: { + indexed: 'SOME-DATE', + name: 'some name', + type: SCThingOriginType.Remote, + }, + type: SCThingType.Message, + uid: 'message-123', + }, + { + audiences: ['employees'], + message: 'Bar Message Text', + name: 'Bar Message', + origin: { + indexed: 'SOME-DATE', + name: 'some name', + type: SCThingOriginType.Remote, + }, + type: SCThingType.Message, + uid: 'message-456', + }, +]; + +const sampleDishes: SCDish[] = [ + { + categories: ['main dish'], + name: 'Foo Dish', + origin: { + indexed: 'SOME-DATE', + name: 'some name', + type: SCThingOriginType.Remote, + }, + type: SCThingType.Dish, + uid: 'dish-123', + }, + { + categories: ['side dish'], + name: 'Bar Dish', + origin: { + indexed: 'SOME-DATE', + name: 'some name', + type: SCThingOriginType.Remote, + }, + type: SCThingType.Dish, + uid: 'dish-456', + }, +]; + +const sampleBuildings: SCBuilding[] = [ + { + categories: ['education'], + geo: { + point: {type: 'Point', coordinates: [12, 12]}, + }, + name: 'Foo Building', + origin: { + indexed: 'SOME-DATE', + name: 'some name', + type: SCThingOriginType.Remote, + }, + type: SCThingType.Building, + uid: 'building-123', + }, +]; + +const sampleRooms: SCRoom[] = [ + { + categories: ['library'], + geo: { + point: {type: 'Point', coordinates: [12, 12]}, + }, + name: 'Foo Room', + origin: { + indexed: 'SOME-DATE', + name: 'some name', + type: SCThingOriginType.Remote, + }, + type: SCThingType.Room, + uid: 'room-123', + }, +]; + +const sampleArticles: SCArticle[] = [ + { + articleBody: 'Foo Text', + categories: ['unipedia'], + name: 'Foo Article', + origin: { + indexed: 'SOME-DATE', + name: 'some name', + type: SCThingOriginType.Remote, + }, + type: SCThingType.Article, + uid: 'article-123', + }, + { + articleBody: 'Bar Text', + categories: ['unipedia'], + name: 'Bar Article', + origin: { + indexed: 'SOME-DATE', + name: 'some name', + type: SCThingOriginType.Remote, + }, + type: SCThingType.Article, + uid: 'article-456', + }, +]; + +const samplePersons: SCPerson[] = [ + { + familyName: 'Person', + givenName: 'Foo', + name: 'Foo Person', + origin: { + indexed: 'SOME-DATE', + name: 'some name', + type: SCThingOriginType.Remote, + }, + type: SCThingType.Person, + uid: 'person-123', + }, + { + familyName: 'Person', + givenName: 'Bar', + name: 'Bar Person', + origin: { + indexed: 'SOME-DATE', + name: 'some name', + type: SCThingOriginType.Remote, + }, + type: SCThingType.Person, + uid: 'person-456', + }, +]; + +const sampleBooks: SCBook[] = [ + { + authors: samplePersons, + isbn: '123456', + name: 'Foo Book', + origin: { + indexed: 'SOME-DATE', + name: 'some name', + type: SCThingOriginType.Remote, + }, + type: SCThingType.Book, + uid: 'book-123', + }, + { + authors: [], + isbn: '123456', + name: 'Bar Book', + origin: { + indexed: 'SOME-DATE', + name: 'some name', + type: SCThingOriginType.Remote, + }, + type: SCThingType.Book, + uid: 'book-234', + }, +]; + +const sampleCatalogs: SCCatalog[] = [ + { + categories: ['university events'], + level: 1, + name: 'Foo Catalog', + origin: { + indexed: 'SOME-DATE', + name: 'some name', + type: SCThingOriginType.Remote, + }, + type: SCThingType.Catalog, + uid: 'catalog-123', + }, + { + categories: ['university events'], + level: 1, + name: 'Bar Catalog', + origin: { + indexed: 'SOME-DATE', + name: 'some name', + type: SCThingOriginType.Remote, + }, + type: SCThingType.Catalog, + uid: 'catalog-456', + }, +]; + +const sampleTodos: SCToDo[] = [ + { + categories: ['foo category'], + done: false, + name: 'Foo Todo', + origin: { + indexed: 'SOME-DATE', + name: 'some name', + type: SCThingOriginType.Remote, + }, + priority: SCToDoPriority.LOW, + type: SCThingType.ToDo, + uid: 'todo-123', + }, + { + categories: ['bar category'], + done: true, + name: 'Bar Todo', + origin: { + indexed: 'SOME-DATE', + name: 'some name', + type: SCThingOriginType.Remote, + }, + priority: SCToDoPriority.HIGH, + type: SCThingType.ToDo, + uid: 'todo-456', + }, +]; + +const sampleFavorites: SCFavorite[] = [ + { + data: sampleBuildings[0], + name: 'Foo Favorite', + origin: { + created: 'SOME-DATE', + type: SCThingOriginType.User, + }, + type: SCThingType.Favorite, + uid: 'favorite-123', + }, + { + data: samplePersons[1], + name: 'Bar Favorite', + origin: { + created: 'SOME-DATE', + type: SCThingOriginType.User, + }, + type: SCThingType.Favorite, + uid: 'favorite-456', + }, +]; + +const sampleAcademicEvents: SCAcademicEvent[] = [ + { + categories: ['course'], + majors: ['Major One', 'Major Two'], + name: 'Foo Academic Event', + origin: { + indexed: 'SOME-DATE', + name: 'some name', + type: SCThingOriginType.Remote, + }, + performers: samplePersons, + type: SCThingType.AcademicEvent, + uid: 'academic-event-123', + }, + { + categories: ['practicum'], + majors: ['Major Two', 'Major Three'], + name: 'Bar Academic Event', + origin: { + indexed: 'SOME-DATE', + name: 'some name', + type: SCThingOriginType.Remote, + }, + performers: samplePersons, + type: SCThingType.AcademicEvent, + uid: 'academic-event-456', + }, +]; + +const sampleDateSeries: SCDateSeries[] = [ + { + dates: ['2019-03-01T17:00:00+00:00', '2019-03-08T17:00:00+00:00'], + duration: 'PT2H', + event: sampleAcademicEvents[0], + frequency: 'once', + name: 'Foo Date Event - Date Series', + origin: { + indexed: 'SOME-DATE', + name: 'some name', + type: SCThingOriginType.Remote, + }, + type: SCThingType.DateSeries, + uid: 'date-series-123', + }, + { + dates: ['2019-03-03T10:00:00+00:00', '2019-03-11T10:00:00+00:00'], + duration: 'PT2H', + event: sampleAcademicEvents[1], + frequency: 'weekly', + name: 'Bar Date Event - Date Series', + origin: { + indexed: 'SOME-DATE', + name: 'some name', + type: SCThingOriginType.Remote, + }, + type: SCThingType.DateSeries, + uid: 'date-series-456', + }, +]; + +export const sampleThingsMap: {[key in SCThingType | string]: SCThing[]} = { + 'academic event': sampleAcademicEvents, + article: sampleArticles, + book: sampleBooks, + building: sampleBuildings, + catalog: sampleCatalogs, + 'course of studies': [], + 'date series': sampleDateSeries, + diff: [], + dish: sampleDishes, + favorite: sampleFavorites, + floor: [], + message: sampleMessages, + organization: [], + person: samplePersons, + 'point of interest': [], + room: sampleRooms, + semester: [], + setting: [], + 'sport course': [], + ticket: [], + todo: sampleTodos, + tour: [], + video: [], +}; + +// 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); + } + }); + }); + }); + } else { + Object.keys(sampleThingsMap).forEach((key) => { + sampleThings.push(...sampleThingsMap[key]); + }); + } + return sampleThings; +} diff --git a/src/app/_helpers/fake-backend.interceptor.ts b/src/app/_helpers/fake-backend.interceptor.ts new file mode 100644 index 00000000..32f21332 --- /dev/null +++ b/src/app/_helpers/fake-backend.interceptor.ts @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2018, 2019 StApps + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ +import {HTTP_INTERCEPTORS, HttpEvent, + HttpHandler, HttpInterceptor, HttpRequest, HttpResponse} from '@angular/common/http'; +import {Injectable} from '@angular/core'; +import {SCThing} from '@openstapps/core'; +import {Observable, of} from 'rxjs'; +import {getSampleThings} from './data/sampleThings'; + +@Injectable() +export class FakeBackendInterceptor implements HttpInterceptor { + // tslint:disable-next-line:no-empty + constructor() { + } + + intercept(request: HttpRequest, next: HttpHandler): Observable> { + let data: SCThing[] = []; + // fake responses for search requests for easier (backendless) development process + if (request.url.endsWith('/search') && request.method === 'POST') { + if (typeof request.body.filter !== 'undefined' && typeof request.body.filter.arguments !== 'undefined') { + if (request.body.filter.arguments.field === 'uid') { + // provide items with given uid for search requests requesting single items (detail view) + data = getSampleThings(request.body.filter.arguments.value); + } + } else { + // if filter and arguments are not set, then provide all sample items (things) + data = getSampleThings(); + } + // fake a response of the backend with previously defined data + return of(new HttpResponse({status: 200, body: {data: data}})); + } else { + // for all other requests, forward the requests to actually requested URL (backend) + return next.handle(request); + } + } +} + +export const fakeBackendProvider = { + multi: true, + provide: HTTP_INTERCEPTORS, + useClass: FakeBackendInterceptor, +}; diff --git a/src/app/app.module.ts b/src/app/app.module.ts index d0f22f7b..cb885e9b 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -23,6 +23,7 @@ import {StatusBar} from '@ionic-native/status-bar/ngx'; import {IonicModule, IonicRouteStrategy} from '@ionic/angular'; import {TranslateLoader, TranslateModule} from '@ngx-translate/core'; import {TranslateHttpLoader} from '@ngx-translate/http-loader'; +import {fakeBackendProvider} from './_helpers/fake-backend.interceptor'; import {AppRoutingModule} from './app-routing.module'; import {AppComponent} from './app.component'; import {ConfigModule} from './modules/config/config.module'; @@ -59,6 +60,8 @@ export function createTranslateLoader(http: HttpClient) { CommonModule, ], providers: [ + // use fake backend in place of Http service for backendless development + fakeBackendProvider, StatusBar, SplashScreen, {provide: RouteReuseStrategy, useClass: IonicRouteStrategy},