From 92d0e94582aa01dad3d7fcaea84276fe1c0b9a65 Mon Sep 17 00:00:00 2001 From: Arno Kaimbacher Date: Tue, 21 Sep 2021 16:13:58 +0200 Subject: [PATCH] - add themes.css - add DatasetService.ts and InternalIdHandler --- angular.json | 2 +- src/app/app.module.ts | 18 +-- ...dataset-by-station-selector.component.html | 56 +++++++-- .../dataset-by-station-selector.component.ts | 25 +++-- src/app/map/base-map.component.ts | 1 + src/app/services/dataset-api.service.ts | 25 ++++- src/app/services/dataset.service.ts | 70 ++++++++++++ .../services/internal-id-handler.service.ts | 34 ++++++ src/general/themes.scss | 106 ++++++++++++++++++ src/shared/models/dataset.ts | 18 ++- src/styles.scss | 11 +- 11 files changed, 327 insertions(+), 39 deletions(-) create mode 100644 src/app/services/dataset.service.ts create mode 100644 src/common/components/services/internal-id-handler.service.ts create mode 100644 src/general/themes.scss diff --git a/angular.json b/angular.json index f43bb99..30b98e5 100644 --- a/angular.json +++ b/angular.json @@ -58,7 +58,7 @@ { "type": "initial", "maximumWarning": "500kb", - "maximumError": "1mb" + "maximumError": "2mb" }, { "type": "anyComponentStyle", diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 4554073..ef4bf20 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -18,30 +18,30 @@ import { HttpService } from "./services/http.service"; import { StationService } from "./services/station.service"; import { MessagesComponent } from './messages/messages.component'; import { MessageService } from "./services/message.service"; +import { DatasetService } from "./services/dataset.service"; import { MapService } from '../common/components/services/map.service'; import { BarComponent } from './components/bar/bar.component'; // import { LocateService } from '@helgoland/map'; // import { MapCache } from '@helgoland/map'; - -// siehe https://52north.github.io/helgoland-toolbox/additional-documentation/how-tos/integrate-a-map-component.html -// https://52north.github.io/helgoland-toolbox/components/LocateControlComponent.html#source - import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { MatDialogModule } from '@angular/material/dialog'; import { DatasetByStationSelectorComponent } from './components/dataset-by-station-selector/dataset-by-station-selector.component'; // import { MAT_DIALOG_DEFAULT_OPTIONS } from '@angular/material'; +import { MatListModule } from '@angular/material/list'; + +import { InternalIdHandler } from '../common/components/services/internal-id-handler.service'; @NgModule({ // declarations: The components, directives, and pipes that belong to this NgModule. declarations: [AppComponent, MapComponent, DashboardComponent, MessagesComponent, MapViewComponent, BarComponent, DatasetByStationSelectorComponent], - entryComponents: [ - DatasetByStationSelectorComponent - ], + // entryComponents: [ + // DatasetByStationSelectorComponent + // ], // imports: Other modules whose exported classes are needed by component templates declared in this NgModule. - imports: [BrowserModule, HttpClientModule, AppRoutingModule, ComponentsModule, BrowserAnimationsModule, MatDialogModule], + imports: [BrowserModule, HttpClientModule, AppRoutingModule, ComponentsModule, BrowserAnimationsModule, MatDialogModule, MatListModule], providers: [ - MarkerService, PopupService, HttpService, DatasetApiService, StationService, MessageService, MapService, + MarkerService, PopupService, HttpService, DatasetApiService, StationService, MessageService, MapService,DatasetService, InternalIdHandler // { // provide: DatasetApiInterface, diff --git a/src/app/components/dataset-by-station-selector/dataset-by-station-selector.component.html b/src/app/components/dataset-by-station-selector/dataset-by-station-selector.component.html index 4658e62..5b563eb 100644 --- a/src/app/components/dataset-by-station-selector/dataset-by-station-selector.component.html +++ b/src/app/components/dataset-by-station-selector/dataset-by-station-selector.component.html @@ -27,22 +27,58 @@ -

{{platform?.label}}

+

{{platform?.label}}

- - - - + + + +
+ {{counter}} timeseries are loading... +
+ + + + +
+ {{ timeseries.parameters.phenomenon.label }} +
+
+ Sensor: {{ timeseries.parameters.procedure.label }} + {{ timeseries.internalId }} + ({{timeseries.parameters.category.label}}) +
+
+ {{timeseries.lastValue.value}} + {{timeseries.uom}} +
+
+
+
- - +
+
\ No newline at end of file diff --git a/src/app/components/dataset-by-station-selector/dataset-by-station-selector.component.ts b/src/app/components/dataset-by-station-selector/dataset-by-station-selector.component.ts index ebc3ec4..f9e2677 100644 --- a/src/app/components/dataset-by-station-selector/dataset-by-station-selector.component.ts +++ b/src/app/components/dataset-by-station-selector/dataset-by-station-selector.component.ts @@ -7,6 +7,8 @@ import { Station } from './../../../shared/models/station'; import { MatDialogRef } from '@angular/material/dialog'; +import { DatasetService } from '../../services/dataset.service'; + // https://material.angular.io/components/dialog/overview // https://blog.angular-university.io/angular-material-dialog/ // https://github.com/angular-university/angular-material-course/blob/3-dialog-finished/src/app/course-dialog/course-dialog.component.html @@ -47,6 +49,7 @@ export class DatasetByStationSelectorComponent implements OnInit { constructor( protected datasetApiService: DatasetApiService, private dialogRef: MatDialogRef, + public datasetService : DatasetService ) { } public ngOnInit() { @@ -72,20 +75,24 @@ export class DatasetByStationSelectorComponent implements OnInit { public toggle(timeseriesDataset: SelectableDataset) { timeseriesDataset.selected = !timeseriesDataset.selected; - this.updateSelection(); + this.updateSelection(); } protected prepareResult(result: SelectableDataset, selection: boolean) { + if (this.datasetService.hasDataset(result.internalId)) { + selection = true; + } result.selected = selection; - if (this.phenomenonId) { - if (result.parameters.phenomenon.id === this.phenomenonId) { - this.phenomenonMatchedList.push(result); - } else { - this.othersList.push(result); - } - } else { + // if (this.phenomenonId) { + // if (result.parameters.phenomenon.id === this.phenomenonId) { + // this.phenomenonMatchedList.push(result); + // } else { + // this.othersList.push(result); + // } + // } + // else { this.phenomenonMatchedList.push(result); - } + // } this.updateSelection(); } diff --git a/src/app/map/base-map.component.ts b/src/app/map/base-map.component.ts index b23593b..f6a5cac 100644 --- a/src/app/map/base-map.component.ts +++ b/src/app/map/base-map.component.ts @@ -89,6 +89,7 @@ export abstract class BaseMapComponent implements OnChanges, OnInit { this.map = new Map(this.mapId, this.mapOptions); this.mapService.setMap(this.mapId, this.map); this.onMapInitializedEvent.emit(this.mapId); + if (this.baseMaps && this.baseMaps.size > 0) { this.baseMaps.forEach((layerOptions, key) => this.addBaseMap(layerOptions)); } else { diff --git a/src/app/services/dataset-api.service.ts b/src/app/services/dataset-api.service.ts index bcc37f3..b2a6926 100644 --- a/src/app/services/dataset-api.service.ts +++ b/src/app/services/dataset-api.service.ts @@ -14,8 +14,9 @@ import { MessageService } from './message.service'; import { GeomonPlatform } from '../../shared/models/platform'; import { Dataset, GeomonTimeseries } from '../../shared/models/dataset'; +import { deserialize } from 'class-transformer'; import { map } from 'rxjs/operators'; - +import { InternalIdHandler } from '../../common/components/services/internal-id-handler.service'; // @Injectable({ // providedIn: 'root' // }) @@ -27,7 +28,8 @@ export class DatasetApiService { constructor( private httpClient: HttpClient, protected httpService: HttpService, - private messageService: MessageService) { + private messageService: MessageService, + protected internalDatasetId: InternalIdHandler,) { } public getPhenomena(apiUrl: string, params?: any, options?: any) { @@ -73,13 +75,24 @@ export class DatasetApiService { public getDataset(id: string, apiUrl: string, params?: any, options?: HttpRequestOptions): Observable { const url = this.createRequestUrl(apiUrl, 'datasets', id); - return this.requestApi(url, params, options); - //.pipe( - // map((res) => this.prepareDataset(res, apiUrl)) - // ); + return this.requestApi(url, params, options) + .pipe( + map((res) => this.prepareDataset(res, apiUrl)) + ); } //#region Helper method + + private prepareDataset(datasetObj:GeomonTimeseries, apiUrl: string) { + let dataset = deserialize(GeomonTimeseries, JSON.stringify(datasetObj)); + dataset.url = apiUrl; + this.internalDatasetId.generateInternalId(dataset); + // if (dataset.seriesParameters) { + // dataset.parameters = dataset.seriesParameters; + // delete dataset.seriesParameters; + // } + return dataset; + } protected createGeomonPlatform(feature: Station): GeomonPlatform { const datasetIds = []; diff --git a/src/app/services/dataset.service.ts b/src/app/services/dataset.service.ts new file mode 100644 index 0000000..2b6baab --- /dev/null +++ b/src/app/services/dataset.service.ts @@ -0,0 +1,70 @@ +import { Injectable } from '@angular/core'; +import { EventEmitter } from '@angular/core'; + +@Injectable() +export class DatasetService { + + public datasetIds: string[] = []; + public datasetService: Map = new Map(); + + public datasetIdsChanged: EventEmitter = new EventEmitter(); + + /** + * Adds the dataset to the selection + * + * @param internalId + * @param [options] + * @returns Successfull added the dataset. + */ + public addDataset(internalId: string, options?: T): boolean { + if (this.datasetIds.indexOf(internalId) < 0) { + this.datasetIds.push(internalId); + // if (options) { + // this.datasetOptions.set(internalId, options); + // } else { + // this.datasetOptions.set(internalId, this.createStyles(internalId)); + // } + // this.saveState(); + } + // else if (options instanceof Array) { + // const temp = (this.datasetOptions.get(internalId) as DatasetOptions[]); + // options.forEach((e) => temp.push(e)); + // // this.saveState(); + // } + this.datasetService.set(internalId, options); + + this.datasetIdsChanged.emit(this.datasetIds); + return true; + } + + public removeAllDatasets() { + this.datasetIds.length = 0; + this.datasetService.clear(); + this.datasetIdsChanged.emit(this.datasetIds); + // this.saveState(); + } + + public removeDataset(internalId: string) { + const datasetIdx = this.datasetIds.indexOf(internalId); + if (datasetIdx > -1) { + this.datasetIds.splice(datasetIdx, 1); + this.datasetService.delete(internalId); + } + this.datasetIdsChanged.emit(this.datasetIds); + // this.saveState(); + } + + public hasDatasets(): boolean { + return this.datasetIds.length > 0; + } + + public hasDataset(id: string): boolean { + // return this.datasetIds.indexOf(id) >= 0; + return this.datasetService.has(id); + } + + public updateDatasetOptions(options: T, internalId: string) { + this.datasetService.set(internalId, options); + // this.saveState(); + } +} \ No newline at end of file diff --git a/src/common/components/services/internal-id-handler.service.ts b/src/common/components/services/internal-id-handler.service.ts new file mode 100644 index 0000000..8a8de71 --- /dev/null +++ b/src/common/components/services/internal-id-handler.service.ts @@ -0,0 +1,34 @@ +import { Injectable } from '@angular/core'; +import { IDataset } from '../../../shared/models/dataset'; + +const INTERNAL_ID_SEPERATOR = '_'; + +// export interface InternalDatasetId { +// id: string; +// url: string; +// } + +/** + * Service to generate or resolve internal dataset IDs + */ +@Injectable() +export class InternalIdHandler { + /** + * Generates and set an internal id for the given dataset. + * @param dataset The dataset for which the internal id will be generated and saved. + */ + public generateInternalId(dataset: IDataset) { + dataset.internalId = dataset.url + INTERNAL_ID_SEPERATOR + dataset.id; + } + + /** + * Creates an internal id out of the parameters + * @param url - service url + * @param id - service specific id + * @returns - the internal id + */ + public createInternalId(url: string, id: string): string { + return url + INTERNAL_ID_SEPERATOR + id; + } + +} diff --git a/src/general/themes.scss b/src/general/themes.scss new file mode 100644 index 0000000..895d202 --- /dev/null +++ b/src/general/themes.scss @@ -0,0 +1,106 @@ +// Include non-theme styles for core. + +/* You can add global styles to this file, and also import other style files */ +// @import "~@angular/material/_theming.scss"; +@import '../../node_modules/@angular/material/theming'; +// @import "~@angular/material/prebuilt-themes/indigo-pink.css"; +@import "~@angular/material/prebuilt-themes/purple-green.css"; + +body, +html { + margin: 0 auto; + height: 100% !important; +} + +$dark-text: #000000; +$dark-primary-text: rgba($dark-text, 0.87); +// Dark Theme text +$light-text: #ffffff; +$light-primary-text: $light-text; + +// Define the palettes for your theme using the Material Design palettes available in palette.scss +// (imported above). For each palette, you can optionally specify a default, lighter, and darker +// hue. +.app-theme1-theme { + + // $my-app-primary: mat-palette($mat-grey, 100); + $mat-primary: ( + main: #66c5e4, + lighter: #d1eef7, + darker: #49b0d9, + 200: #66c5e4, + // For slide toggle, + contrast: + ( + main: $dark-primary-text, + lighter: $dark-primary-text, + darker: $dark-primary-text, + ), + ); + $theme-primary: mat-palette($mat-primary, main, lighter, darker); + + body { + --accent-color: #626250; + --accent-lighter-color: #d0d0cb; + --accent-darker-color: #464637; + --text-accent-color: #{$light-primary-text}; + --text-accent-lighter-color: #{$dark-primary-text}; + --text-accent-darker-color: #{$light-primary-text}; + } + + // $my-app-accent: mat-palette($mat-grey, 500); + $mat-accent: ( + main: #626250, + lighter: #d0d0cb, + darker: #464637, + 200: #626250, + // For slide toggle, + contrast: + ( + main: $light-primary-text, + lighter: $dark-primary-text, + darker: $light-primary-text, + ), + ); + $theme-accent: mat-palette($mat-accent, main, lighter, darker); + + // $my-app-warn: mat-palette($mat-grey, 900); + body { + --warn-color: #ff0000; + --warn-lighter-color: #ffb3b3; + --warn-darker-color: #ff0000; + --text-warn-color: #{$light-primary-text}; + --text-warn-lighter-color: #{$dark-primary-text}; + --text-warn-darker-color: #{$light-primary-text}; + } + + $mat-warn: ( + main: #ff0000, + lighter: #ffb3b3, + darker: #ff0000, + 200: #ff0000, + // For slide toggle, + contrast: + ( + main: $light-primary-text, + lighter: $dark-primary-text, + darker: $light-primary-text, + ), + ); + $theme-warn: mat-palette($mat-warn, main, lighter, darker); + + // Create the theme object (a Sass map containing all of the palettes). + $my-app-theme: mat-light-theme($mat-primary, $theme-accent, $theme-warn); + // Include theme styles for core and each component used in your app. + // Alternatively, you can import and @include the theme mixins for each component + // that you are using. + @include angular-material-theme($my-app-theme); +} + +.app-theme2-theme { + $alternate-primary: mat-palette($mat-indigo, 100); + $alternate-accent: mat-palette($mat-indigo, 500); + $alternate-warn: mat-palette($mat-indigo, 900); + $alternate-theme: mat-light-theme($alternate-primary, $alternate-accent, $alternate-warn); + @include angular-material-theme($alternate-theme); +} diff --git a/src/shared/models/dataset.ts b/src/shared/models/dataset.ts index 729fd22..500ffca 100644 --- a/src/shared/models/dataset.ts +++ b/src/shared/models/dataset.ts @@ -1,5 +1,7 @@ import { GeomonPlatform } from "./platform"; +const INTERNAL_ID_SEPERATOR = '_'; + export class Dataset { public id: string; public label: string; @@ -16,6 +18,17 @@ export class Dataset { public parameters: any; } +export interface IDataset extends Parameter { + url: string; + uom: string; + internalId: string; + firstValue: FirstLastValue; + lastValue: FirstLastValue; + referenceValues: ReferenceValue[]; + parameters: ParameterConstellation; + renderingHints: RenderingHints; +} + export class GeomonDataset { public internalId: string; @@ -26,6 +39,9 @@ export class GeomonDataset { ) { // this.internalId = new InternalIdHandler().createInternalId(url, id); } + // public get internalId(): string { + // return this.url + INTERNAL_ID_SEPERATOR + this.id; + // } } export class GeomonTimeseries extends GeomonDataset { @@ -43,7 +59,7 @@ export class GeomonTimeseries extends GeomonDataset { public parameters: ParameterConstellation, ) { super(id, url, label); - } + } } export class ParameterConstellation { diff --git a/src/styles.scss b/src/styles.scss index 20d0799..0da99f3 100644 --- a/src/styles.scss +++ b/src/styles.scss @@ -11,7 +11,11 @@ @import '~leaflet/dist/leaflet.css'; // Import a Google Font -@import url('https://fonts.googleapis.com/css?family=Nunito:400,700'); +// @import url('https://fonts.googleapis.com/css?family=Nunito:400,700'); +@import url('https://fonts.googleapis.com/css?family=Roboto:300,400,500'); + +// @import './general/themes.scss'; + // @import "~bulma/css/bulma.css"; // 1. Import the initial variables @@ -34,7 +38,7 @@ $select-green: #03a678; // Update Bulma's global variables // Update the sans-serif font family -$family-sans-serif: "Nunito", sans-serif; +$family-sans-serif: "Roboto", sans-serif; // 3. Set the derived variables $grey-dark: $brown; @@ -78,7 +82,8 @@ body { width: 100%; line-height: 1.6; font-weight: 400; - font-family: "Raleway", "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif; + // font-family: "Raleway", "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-family: Roboto, "Helvetica Neue", sans-serif; color: #222; }