-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #214 from e-picsa/feat/climate-dashboard
Feat(dashboard); climate summaries
- Loading branch information
Showing
34 changed files
with
755 additions
and
64 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
91 changes: 86 additions & 5 deletions
91
apps/picsa-apps/dashboard/src/app/modules/climate-data/climate-data-api.service.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,99 @@ | ||
import { Injectable } from '@angular/core'; | ||
import { PicsaNotificationService } from '@picsa/shared/services/core/notification.service'; | ||
import createClient from 'openapi-fetch'; | ||
|
||
import { paths } from './types/api'; | ||
|
||
const API_ENDPOINT = 'https://api.epicsa.idems.international'; | ||
|
||
/** Service to interact with external PICSA Climate API */ | ||
/** Custom client which tracks responses by callback id */ | ||
type ICallbackClient = (id:string)=>ReturnType<typeof createClient<paths>> | ||
|
||
/** Type-safe http client with added support for callbacks */ | ||
type IClient = ReturnType<typeof createClient<paths>> & {useMeta:ICallbackClient} | ||
|
||
|
||
|
||
interface IMetaEntry{ | ||
status:'pending' | 'success' | 'error' | 'unknown', | ||
rawResponse?:Response, | ||
} | ||
|
||
|
||
/** | ||
* Service to interact with external PICSA Climate API | ||
* All methods are exposed through a type-safe `client` property, or can additionally use | ||
* a custom client that includes status notification updates via the `useMeta` method | ||
* @example | ||
* Use custom callback that will show user notifications on error and record to service | ||
* ```ts | ||
* const {response, data, error} = await api.useMeta('myRequestId').POST(...) | ||
* ``` | ||
* Use default client without additional callbacks | ||
* ```ts | ||
* const {response, data, error} = await api.client.POST(...) | ||
* ``` | ||
* */ | ||
@Injectable({ providedIn: 'root' }) | ||
export class ClimateDataApiService { | ||
|
||
/** Request additional meta by id */ | ||
public meta:Record<string ,IMetaEntry>={} | ||
|
||
/** Http client with type-definitions for API endpoints */ | ||
public client:ReturnType<typeof createClient<paths>> | ||
|
||
constructor() { | ||
this.client = createClient<paths>({ baseUrl: API_ENDPOINT,mode:'cors' }); | ||
public client:IClient | ||
|
||
constructor(private notificationService:PicsaNotificationService) { | ||
const client = createClient<paths>({ baseUrl: API_ENDPOINT,mode:'cors' }); | ||
this.client = {...client,useMeta:()=>{ | ||
return client | ||
}} | ||
} | ||
|
||
|
||
/** | ||
* Provide an id which which will be updated alongside requests. | ||
* The cache will also include interceptors to provide user notification on error | ||
**/ | ||
public useMeta(id:string){ | ||
const customFetch = this.createCustomFetchClient(id) | ||
const customClient = createClient<paths>({ baseUrl: API_ENDPOINT,mode:'cors',fetch:customFetch }); | ||
return customClient | ||
} | ||
|
||
/** Create a custom implementation of fetch client to handle status updates and notifications */ | ||
private createCustomFetchClient(id:string){ | ||
return async (...args:Parameters<typeof window['fetch']>)=>{ | ||
this.meta[id]={status:'pending'} | ||
const response = await window.fetch(...args); | ||
this.meta[id].status = this.getCallbackStatus(response.status) | ||
this.meta[id].rawResponse = response | ||
if(this.meta[id].status ==='error' ){ | ||
await this.showCustomFetchErrorMessage(id,response) | ||
} | ||
return response | ||
} | ||
} | ||
|
||
/** Show error message when using custom fetch with callbacks */ | ||
private async showCustomFetchErrorMessage(id:string,response:Response){ | ||
// clone body so that open-api can still consume when constructing full fetch response | ||
const clone = response.clone() | ||
try { | ||
const json = await clone.json() | ||
const errorText = json.detail || 'failed, see console logs for details' | ||
this.notificationService.showUserNotification({matIcon:'error',message:`[${id}] ${errorText}`}) | ||
} catch (error) { | ||
console.error(error) | ||
console.error('Fetch Error',error) | ||
this.notificationService.showUserNotification({matIcon:'error',message:`[${id}] 'failed, see console logs for details'`}) | ||
} | ||
} | ||
|
||
private getCallbackStatus(statusCode:number):IMetaEntry['status']{ | ||
if(200 <= statusCode && statusCode <=299) return 'success' | ||
if(400 <= statusCode && statusCode <=499) return 'error' | ||
if(500 <= statusCode && statusCode <=599) return 'error' | ||
return 'unknown' | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
5 changes: 3 additions & 2 deletions
5
...a-apps/dashboard/src/app/modules/climate-data/pages/home/climate-data-home.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
29 changes: 29 additions & 0 deletions
29
.../app/modules/climate-data/pages/station/components/rainfall-summary/rainfall-summary.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
<div style="display: flex; align-items: center"> | ||
<h3 style="flex: 1">Rainfall Summary</h3> | ||
<button mat-stroked-button (click)="refreshData()" [disabled]="res.status==='pending'"> | ||
<mat-icon [class.spin]="res.status==='pending'">autorenew</mat-icon> | ||
Refresh Data | ||
</button> | ||
</div> | ||
<mat-tab-group preserveContent> | ||
<mat-tab> | ||
<ng-template mat-tab-label> | ||
<mat-icon>view_list</mat-icon> | ||
Table | ||
</ng-template> | ||
<picsa-data-table [data]="summary.data" [options]="tableOptions"></picsa-data-table> | ||
</mat-tab> | ||
<!-- <mat-tab> | ||
<ng-template mat-tab-label> | ||
<mat-icon>show_chart</mat-icon> | ||
Chart | ||
</ng-template> | ||
</mat-tab> --> | ||
<mat-tab> | ||
<ng-template mat-tab-label> | ||
<mat-icon>description</mat-icon> | ||
Definition | ||
</ng-template> | ||
<pre>{{summary.metadata | json}}</pre> | ||
</mat-tab> | ||
</mat-tab-group> |
25 changes: 25 additions & 0 deletions
25
.../app/modules/climate-data/pages/station/components/rainfall-summary/rainfall-summary.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
:host { | ||
display: block; | ||
} | ||
|
||
mat-icon.spin { | ||
animation: spin 2s linear infinite; | ||
} | ||
|
||
@-webkit-keyframes spin { | ||
0% { | ||
-webkit-transform: rotate(0deg); | ||
} | ||
100% { | ||
-webkit-transform: rotate(360deg); | ||
} | ||
} | ||
|
||
@keyframes spin { | ||
0% { | ||
transform: rotate(0deg); | ||
} | ||
100% { | ||
transform: rotate(360deg); | ||
} | ||
} |
Oops, something went wrong.