Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat.river gauges test #1475

Merged
merged 36 commits into from
Dec 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
3ee918a
feat: add river gauge pin AB#25130
arsforza Dec 1, 2023
99fa03b
feat: add gauges to legend AB#25130
arsforza Dec 1, 2023
961f40f
feat: mock data reference & previous water level
jannisvisser Dec 1, 2023
f5cd837
Merge branch 'feat.river-gauges-MWI' of https://github.com/rodekruis/…
jannisvisser Dec 1, 2023
511845a
WIP refactor dynamic point popup AB#25131
arsforza Dec 4, 2023
93cc6cd
fix: add key to delete point AB#25179
arsforza Dec 4, 2023
44d9012
refactor: merge point-data-dynamic-status into dynamic-point-data AB#…
jannisvisser Dec 4, 2023
02b0579
fix: index on timestamp AB#25127
jannisvisser Dec 4, 2023
8f98503
fix: real static data AB#25128
jannisvisser Dec 8, 2023
bdd657a
fix: make fid unique AB#25128
jannisvisser Dec 8, 2023
e053ddd
fix: update seed and mock AB#25131
arsforza Dec 5, 2023
80ca4cf
feat: add river gauge popup AB#25131
arsforza Dec 5, 2023
d07c78b
reafactor: move popups to angular component AB#25131
arsforza Dec 8, 2023
9a13271
fix: chane fid to numeric + basics to get out glofas data AB#25126
jannisvisser Dec 11, 2023
9a41aa0
update migration
jannisvisser Dec 11, 2023
3b849d5
refactor: use new popup for glofas AB#25280
arsforza Dec 12, 2023
ead16d6
fix: use correct threshold value AB#25280
arsforza Dec 12, 2023
5ede9ce
feat: handle missing data + small tweaks AB#25131
jannisvisser Dec 12, 2023
135fdbe
refactor: use new endpoint AB#25126
arsforza Dec 12, 2023
4811710
fix: allow forecast or threshold to be 0 AB#25280
jannisvisser Dec 12, 2023
30c7ecb
fix: keep min/med glfofas readable AB#25280
jannisvisser Dec 12, 2023
202a3b9
Merge branch 'feat.river-gauges-MWI' of https://github.com/rodekruis/…
jannisvisser Dec 12, 2023
6686c3b
chore: rm old code AB#25126
jannisvisser Dec 12, 2023
479186c
refactor: reroute old glofas endpoint to new entity + seed static to …
jannisvisser Dec 12, 2023
04792e5
feat: migration for production AB#25126
jannisvisser Dec 12, 2023
afb220e
fix: change yellow/orange AB#25131
jannisvisser Dec 13, 2023
d25b8de
fix: tooltip AB#25280
jannisvisser Dec 13, 2023
413cdb2
refactor: move glofas mock data AB#25126
jannisvisser Dec 15, 2023
b89f483
fix: include point-data-category in dynamic api-call AB#25126
jannisvisser Dec 15, 2023
4d8337d
feat: info popup AB#25132
jannisvisser Dec 15, 2023
bcc4345
fix: tooltip + info popup AB#25132
jannisvisser Dec 15, 2023
c160d3a
Merge branch 'master' of https://github.com/rodekruis/IBF-system into…
jannisvisser Dec 15, 2023
84b6234
fix: info popup AB#25132
jannisvisser Dec 15, 2023
3bb33c3
lint
jannisvisser Dec 15, 2023
76d1373
lint
jannisvisser Dec 15, 2023
8554b29
chore: rm unused unit tests
jannisvisser Dec 15, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
| translate: { supportEmailAddress: supportEmailAddress }
"
color="danger"
class="absolute"
></app-tooltip>
</p>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<div
class="leaflet--dynamic-point-popup--header"
[ngClass]="layerName"
[style]="glofasHeaderStyle"
>
<strong>{{ title }}</strong>
</div>
<div class="leaflet--dynamic-point-popup--content">
<ng-container [ngSwitch]="layerName">
<app-river-gauge-popup-content
*ngSwitchCase="ibfLayerName.gauges"
[data]="riverGauge"
></app-river-gauge-popup-content>
<app-typhoon-trackpoint-popup-content
*ngSwitchCase="ibfLayerName.typhoonTrack"
[data]="typhoonData"
></app-typhoon-trackpoint-popup-content>
<app-glofas-station-popup-content
*ngSwitchCase="ibfLayerName.glofasStations"
[data]="glofasData"
></app-glofas-station-popup-content>
</ng-container>
</div>
<div class="leaflet--dynamic-point-popup--footer" [style]="glofasFooterStyle">
<div>
<strong>{{ footerContent }}</strong>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
.leaflet--dynamic-point-popup--header {
&.gauges {
background: var(--ion-color-ibf-no-alert-primary);
}
&.typhoon_track {
background: var(--ion-color-ibf-primary);
}

color: white;
padding: 8px;
border-radius: 8px 8px 0 0;
}

.leaflet--dynamic-point-popup--content {
padding: 8px;
}

.leaflet--dynamic-point-popup--footer {
&.gauges {
color: var(--ion-color-ibf-no-alert-primary);
}
&.typhoon_track {
color: var(--ion-color-ibf-primary);
}
&.glofas_stations {
color: red;
}

padding: 0 8px;
border-radius: 0 0 8px 8px;

div {
padding: 8px 0;
text-align: center;
border-top: 1px solid var(--ion-color-ibf-grey-light);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import { Component, Input, OnInit } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { LatLng } from 'leaflet';
import { EapAlertClass, EapAlertClasses } from '../../../models/country.model';
import { RiverGauge, Station } from '../../../models/poi.model';
import { IbfLayerName } from '../../../types/ibf-layer';
import { LeadTime } from '../../../types/lead-time';

@Component({
selector: 'app-dynamic-point-popup',
templateUrl: './dynamic-point-popup.component.html',
styleUrls: ['./dynamic-point-popup.component.scss'],
})
export class DynamicPointPopupComponent implements OnInit {
@Input()
public layerName: IbfLayerName;

@Input()
public riverGauge?: RiverGauge;

@Input()
public typhoonTrackPoint?: {
timestamp: string;
category: string;
markerLatLng: LatLng;
passed: boolean;
};

@Input()
public glofasData?: {
station: Station;
leadTime: LeadTime;
eapAlertClasses: EapAlertClasses;
};

public typhoonData: {
timestamp: string;
category: string;
};

public ibfLayerName = IbfLayerName;

public title: string;
public footerContent: string;

public glofasHeaderStyle: string;
public glofasFooterStyle: string;

public eapAlertClass: EapAlertClass;

private allowedLayers = [
IbfLayerName.gauges,
IbfLayerName.typhoonTrack,
IbfLayerName.glofasStations,
];

constructor(private translate: TranslateService) {}

ngOnInit(): void {
if (!this.layerName || !this.allowedLayers.includes(this.layerName)) {
return;
}

if (!this.riverGauge && !this.typhoonTrackPoint && !this.glofasData) {
return;
}

if (this.layerName === IbfLayerName.typhoonTrack) {
this.typhoonData = {
timestamp: this.typhoonTrackPoint.timestamp,
category: this.typhoonTrackPoint.category,
};
}

if (
this.layerName === IbfLayerName.glofasStations &&
this.glofasData.eapAlertClasses
) {
this.eapAlertClass = this.glofasData.eapAlertClasses[
this.glofasData.station.dynamicData.eapAlertClass
];
}

this.title = this.getTitle();
this.footerContent = this.getFooterContent();

this.glofasHeaderStyle =
this.layerName === IbfLayerName.glofasStations
? `background: var(--ion-color-${this.eapAlertClass.color});color: var(--ion-color-${this.eapAlertClass.color}-contrast);`
: '';

this.glofasFooterStyle =
this.layerName === IbfLayerName.glofasStations
? `color: var(--ion-color-${this.eapAlertClass.color}${
this.eapAlertClass.color === 'ibf-yellow' ? '-contrast' : ''
});`
: '';
}

private getTitle(): string {
if (this.layerName === IbfLayerName.gauges) {
return `${this.translate.instant('map-popups.river-gauge.header')} ${
this.riverGauge.fid
} ${this.riverGauge.name}`;
}

if (this.layerName === IbfLayerName.typhoonTrack) {
return `Typhoon track${this.typhoonTrackPoint.passed ? ' (passed)' : ''}`;
}

if (this.layerName === IbfLayerName.glofasStations) {
return `${this.glofasData.station.stationCode} STATION: ${this.glofasData.station.stationName}`;
}

return '';
}

private getFooterContent(): string {
if (this.layerName === IbfLayerName.gauges) {
return !this.riverGauge.dynamicData?.['water-level']
? ''
: this.riverGauge.dynamicData?.['water-level'] <=
this.riverGauge.dynamicData?.['water-level-reference']
? this.translate.instant('map-popups.river-gauge.below')
: this.translate.instant('map-popups.river-gauge.above');
}

if (this.layerName === IbfLayerName.typhoonTrack) {
const lat = `${Math.abs(this.typhoonTrackPoint.markerLatLng.lat).toFixed(
4,
)}° ${this.typhoonTrackPoint.markerLatLng.lat > 0 ? 'N' : 'S'}`;
const lng = `${Math.abs(this.typhoonTrackPoint.markerLatLng.lng).toFixed(
4,
)}° ${this.typhoonTrackPoint.markerLatLng.lng > 0 ? 'E' : 'W'}`;
return `${lat}, ${lng}`;
}

if (this.layerName === IbfLayerName.glofasStations) {
return this.eapAlertClass.label;
}

return '';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<div style="margin-bottom: 4px">
{{ data?.leadTime }} forecast of
<span
title="The amount of water moving down a river at a given time and place"
style="
text-decoration: underline;
text-decoration-style: dotted;
cursor: default;
"
>river discharge</span
>
in m<sup>3</sup>/s
<ng-container *ngIf="data?.station?.forecastReturnPeriod">
<br />
(Corresponding to a return period of
<strong>{{ data?.station?.forecastReturnPeriod }}</strong> years)
</ng-container>
</div>
<app-threshold-bar
[backgroundColor]="barBackgroundColor"
[textColor]="barTextColor"
[barWidth]="triggerWidth"
[barValue]="addComma(barValue)"
thresholdDescription="Trigger activation threshold"
[thresholdValue]="data?.station?.dynamicData?.triggerLevel"
[thresholdPosition]="80"
></app-threshold-bar>
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { Component, Input, OnInit } from '@angular/core';
import { EapAlertClass, EapAlertClasses } from '../../../models/country.model';
import { Station } from '../../../models/poi.model';
import { LeadTime } from '../../../types/lead-time';

@Component({
selector: 'app-glofas-station-popup-content',
templateUrl: './glofas-station-popup-content.component.html',
styleUrls: ['./glofas-station-popup-content.component.css'],
})
export class GlofasStationPopupContentComponent implements OnInit {
@Input()
public data: {
station: Station;
leadTime: LeadTime;
eapAlertClasses: EapAlertClasses;
};

public barValue: number;
public triggerWidth: number;
public barBackgroundColor: string;
public barTextColor: string;
private eapAlertClass: EapAlertClass;

ngOnInit(): void {
if (!this.data) {
return;
}

const difference =
Number(this.data.station.dynamicData.forecastLevel) -
Number(this.data.station.dynamicData.triggerLevel);
const closeMargin = 0.05;
const tooClose =
Math.abs(difference) / this.data.station.triggerLevel < closeMargin;

this.barValue =
difference === 0 || !tooClose
? Number(this.data.station.dynamicData.forecastLevel)
: Number(this.data.station.dynamicData.triggerLevel) +
Math.sign(difference) *
Number(this.data.station.dynamicData.triggerLevel) *
closeMargin;

this.triggerWidth = Math.max(
Math.min(
Math.round(
(this.barValue / Number(this.data.station.dynamicData.triggerLevel)) *
100,
),
115,
),
0,
);

this.eapAlertClass = this.data.eapAlertClasses[
this.data.station.dynamicData.eapAlertClass
];

this.barBackgroundColor = `var(--ion-color-${this.eapAlertClass.color})`;
this.barTextColor = `var(--ion-color-${this.eapAlertClass.color}-contrast)`;
}

public addComma = (n) => Math.round(n).toLocaleString('en-US');
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<ng-container *ngIf="current">
<div
style="margin-bottom: 4px; display: flex; justify-content: space-between"
>
<div>
<ion-label style="font-size: 18px; padding-right: 8px">
<strong>{{ currentString }}</strong>
{{ 'map-popups.river-gauge.unit' | translate }}
{{ 'map-popups.river-gauge.sea-level' | translate }}
</ion-label>
<ion-label
style="margin-right: 4px"
[color]="difference <= 0 ? 'success' : 'danger'"
>
<ion-icon
[name]="difference <= 0 ? 'caret-down-outline' : 'caret-up-outline'"
></ion-icon
>{{ differenceAbsolute }}
{{ 'map-popups.river-gauge.unit' | translate }}</ion-label
>
</div>
<app-tooltip
[value]="'map-popups.river-gauge.tooltip' | translate"
color="ibf-no-alert-primary"
></app-tooltip>
</div>
<div style="margin-bottom: 4px">
<ion-label
><strong>{{
'map-popups.river-gauge.current' | translate
}}</strong></ion-label
>
</div>
<app-threshold-bar
backgroundColor="var(--ion-color-ibf-no-alert-primary)"
textColor="var(--ion-color-ibf-white)"
[barWidth]="triggerWidth"
[barValue]="current + ('map-popups.river-gauge.unit' | translate)"
[thresholdDescription]="'map-popups.river-gauge.normal' | translate"
[thresholdValue]="reference + ('map-popups.river-gauge.unit' | translate)"
[thresholdPosition]="45"
></app-threshold-bar>
</ng-container>
<ng-container *ngIf="!current">
<div
style="margin-bottom: 4px; display: flex; justify-content: space-between"
>
<div>
<ion-label style="font-size: 18px; padding-right: 8px">
{{ 'map-popups.river-gauge.no-data' | translate }}
</ion-label>
</div>
</div>
</ng-container>
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
.leaflet--dynamic-point-popup--header {
background: var(--ion-color-ibf-no-alert-primary);
color: white;
padding: 8px;
border-radius: 8px 8px 0 0;
}

.leaflet--dynamic-point-popup--content {
padding: 8px;
}

.leaflet--dynamic-point-popup--footer {
color: var(--ion-color-ibf-no-alert-primary);
padding: 0 8px;
border-radius: 0 0 8px 8px;

div {
padding: 8px 0;
text-align: center;
border-top: 1px solid var(--ion-color-ibf-grey-light);
}
}
Loading
Loading