From 68fc2a746990e134dc184e753feb9605fdd10ba5 Mon Sep 17 00:00:00 2001 From: Levi Szamek Date: Thu, 2 Nov 2023 12:53:15 +0100 Subject: [PATCH 1/3] feat: add support for selecting and requesting single countries Co-authored-by: jstier --- src/app/app.module.ts | 4 ++- src/app/dashboard/dashboard.component.ts | 11 +++++++-- src/app/dashboard/query/query.component.html | 11 +++++++++ src/app/dashboard/query/query.component.ts | 26 +++++++++++++++++--- src/app/data.service.ts | 12 ++++++--- 5 files changed, 54 insertions(+), 10 deletions(-) diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 0b6f933..a1e7e84 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -19,6 +19,7 @@ import { ToastService } from './toast.service'; import { AboutComponent } from './about/about.component'; import {NgOptimizedImage} from '@angular/common'; import { HelpComponent } from './help/help.component'; +import { NgSelectModule } from '@ng-select/ng-select'; @NgModule({ declarations: [ @@ -40,7 +41,8 @@ import { HelpComponent } from './help/help.component'; AppRoutingModule, HttpClientModule, NgxDaterangepickerMd.forRoot(), - NgOptimizedImage + NgOptimizedImage, + NgSelectModule ], providers: [ DataService, diff --git a/src/app/dashboard/dashboard.component.ts b/src/app/dashboard/dashboard.component.ts index b25f3f6..a560296 100644 --- a/src/app/dashboard/dashboard.component.ts +++ b/src/app/dashboard/dashboard.component.ts @@ -68,6 +68,9 @@ export class DashboardComponent implements OnInit { if(queryParams['interval'] == null) queryParams.interval = this.dataService.defaultIntervalValue + if (queryParams['countries'] == null) + queryParams.countries = '' + this.dataService.updateURL(queryParams) // if all values are present then only below code is executed @@ -81,6 +84,7 @@ export class DashboardComponent implements OnInit { this.summaryMessage = this.formSummaryMessage(queryParams) // fire the request to API + console.log('>>> DashboardComponent >>> queryParams ', queryParams) this.dataService.requestSummary(queryParams).subscribe( { next: res => { // console.log('>>> res = ', res) @@ -144,7 +148,8 @@ export class DashboardComponent implements OnInit { hashtags: queryParams && queryParams.hashtags ? queryParams.hashtags : urlParams.hashtags, interval: queryParams && queryParams.interval ? queryParams.interval : urlParams.interval, start: queryParams && queryParams.start ? queryParams.start : urlParams.start, - end: queryParams && queryParams.end ? queryParams.end : urlParams.end + end: queryParams && queryParams.end ? queryParams.end : urlParams.end, + countries: queryParams && queryParams.countries ? queryParams.countries : urlParams.countries }) } } @@ -152,7 +157,7 @@ export class DashboardComponent implements OnInit { } queryParamsComplete(params: any):boolean{ - return ["start", "end", "interval", "hashtags"].sort().join() === Object.keys(params).sort().join() + return ["start", "end", "interval", "hashtags", "countries"].sort().join() === Object.keys(params).sort().join() } stopIntervalReq() { @@ -186,10 +191,12 @@ export class DashboardComponent implements OnInit { * @returns Object with all query params sepearted */ getQueryParamsFromFragments(fragment: string | null): any { + console.log('>>> getQueryParamsFromFragments >>> fragment = ', fragment) if(fragment == null || fragment.length < 2) return null const tempQueryParams: Array> = fragment?.split('&') .map( q => [q.split('=')[0], q.split('=')[1]]) + console.log('>>> getQueryParamsFromFragments >>> tempQueryParams = ', tempQueryParams) return Object.fromEntries(tempQueryParams) } diff --git a/src/app/dashboard/query/query.component.html b/src/app/dashboard/query/query.component.html index 006dfd3..0dac6c9 100644 --- a/src/app/dashboard/query/query.component.html +++ b/src/app/dashboard/query/query.component.html @@ -54,6 +54,17 @@ + +
+
+ + +
+
+ diff --git a/src/app/dashboard/query/query.component.ts b/src/app/dashboard/query/query.component.ts index 595ecb6..1b48176 100644 --- a/src/app/dashboard/query/query.component.ts +++ b/src/app/dashboard/query/query.component.ts @@ -23,6 +23,10 @@ export class QueryComponent implements OnChanges { value: string; }> | undefined interval: string | undefined // default value as 'P1M' + countryMap: Array<{ + name: string; + value: string; + }> | undefined selectedDateRange: { end: any; start: any; } | undefined; alwaysShowCalendars = true; ranges: any @@ -35,7 +39,9 @@ export class QueryComponent implements OnChanges { private _start = '' private _end = '' currentTimeInUTC!: string; - + + countries: string[] = []; + constructor( private dataService: DataService, private router: Router, @@ -151,6 +157,9 @@ export class QueryComponent implements OnChanges { // set interval this.interval = data.interval + + //set countries + this.countries = data.countries } } @@ -162,7 +171,7 @@ export class QueryComponent implements OnChanges { return this.dataService.requestMetadata() - // console.log('>>> QueryComponent >>> getStatistics', this.selectedDateRange) + console.log('>>> QueryComponent >>> getStatistics', this.selectedDateRange) // get all values from form if(! this.selectedDateRange) return @@ -176,7 +185,7 @@ export class QueryComponent implements OnChanges { // update the url fragment this.router.navigate([], { - fragment: `hashtags=${tempHashTags}&start=${tempStart}&end=${tempEnd}&interval=${this.interval}` + fragment: `hashtags=${tempHashTags}&start=${tempStart}&end=${tempEnd}&interval=${this.interval}&countries=${this.countries}`, }) } @@ -258,4 +267,15 @@ export class QueryComponent implements OnChanges { .map(h => encodeURIComponent(h)); // escape everyting but A–Z a–z 0–9 - _ . ! ~ * ' ( ) return cleanedHashtags.join(','); } + + selectedCountries: string[] = []; + allCountries = [ + { name: 'India', value: 'IND' }, + { name: 'USA', value: 'USA' }, + { name: 'Australia', value: 'AUS' }, + { name: 'Canada', value: 'CAN' }, + { name: 'South Africa', value: 'SA' }, + ] + + } diff --git a/src/app/data.service.ts b/src/app/data.service.ts index b4d9592..da364d2 100644 --- a/src/app/data.service.ts +++ b/src/app/data.service.ts @@ -55,7 +55,8 @@ export class DataService { hashtags: queryParams && queryParams.hashtags ? queryParams.hashtags : this.defaultHashtag, interval: queryParams && queryParams.interval ? queryParams.interval : this.defaultIntervalValue, start: queryParams && queryParams.start ? queryParams.start : tempStart.toISOString(), - end: queryParams && queryParams.end ? queryParams.end : this.maxDate + end: queryParams && queryParams.end ? queryParams.end : this.maxDate, + countries: queryParams && queryParams.countries ? queryParams.countries : '' }) }) } @@ -80,7 +81,7 @@ export class DataService { } requestSummary(params: any): Observable { - return this.http.get(`${this.url}/stats/${params['hashtags']}?startdate=${params['start']}&enddate=${params['end']}`) + return this.http.get(`${this.url}/stats/${params['hashtags']}?startdate=${params['start']}&enddate=${params['end']}&countries=${params['countries']}`) .pipe( takeUntil(this.abortSummaryReqSub) ) @@ -144,7 +145,8 @@ export class DataService { start: tempStart.toISOString(), end: this.maxDate, hashtags: this.defaultHashtag, - interval: this.defaultIntervalValue + interval: this.defaultIntervalValue, + countries: '' } } @@ -160,7 +162,7 @@ export class DataService { updateURL(data: IQueryParam): void{ this.router.navigate([], { - fragment: `hashtags=${data.hashtags}&start=${data.start}&end=${data.end}&interval=${data.interval}` + fragment: `hashtags=${data.hashtags}&start=${data.start}&end=${data.end}&interval=${data.interval}&countries=${data.countries}` }) } } @@ -190,6 +192,7 @@ export interface IQueryData { end: string hashtags: Array interval: string + countries: Array } export interface IWrappedPlotData { @@ -230,6 +233,7 @@ export interface ITrendingHashtags { } export interface IQueryParam { + countries: string, hashtags: string, start: string, // date in ISO format, ensure to keep milliseconds as 0 end: string, // date in ISO format, ensure to keep milliseconds as 0 From bcf06fefe2456445482137d0d34bd594adc9aa63 Mon Sep 17 00:00:00 2001 From: Levi Szamek Date: Thu, 2 Nov 2023 14:46:24 +0100 Subject: [PATCH 2/3] fix: tests now work with countries param --- src/app/dashboard/dashboard.component.ts | 3 --- src/app/dashboard/query/query.component.ts | 3 +-- src/app/data.service.spec.ts | 5 +++-- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/app/dashboard/dashboard.component.ts b/src/app/dashboard/dashboard.component.ts index a560296..6fc1325 100644 --- a/src/app/dashboard/dashboard.component.ts +++ b/src/app/dashboard/dashboard.component.ts @@ -84,7 +84,6 @@ export class DashboardComponent implements OnInit { this.summaryMessage = this.formSummaryMessage(queryParams) // fire the request to API - console.log('>>> DashboardComponent >>> queryParams ', queryParams) this.dataService.requestSummary(queryParams).subscribe( { next: res => { // console.log('>>> res = ', res) @@ -191,12 +190,10 @@ export class DashboardComponent implements OnInit { * @returns Object with all query params sepearted */ getQueryParamsFromFragments(fragment: string | null): any { - console.log('>>> getQueryParamsFromFragments >>> fragment = ', fragment) if(fragment == null || fragment.length < 2) return null const tempQueryParams: Array> = fragment?.split('&') .map( q => [q.split('=')[0], q.split('=')[1]]) - console.log('>>> getQueryParamsFromFragments >>> tempQueryParams = ', tempQueryParams) return Object.fromEntries(tempQueryParams) } diff --git a/src/app/dashboard/query/query.component.ts b/src/app/dashboard/query/query.component.ts index 1b48176..d55a7db 100644 --- a/src/app/dashboard/query/query.component.ts +++ b/src/app/dashboard/query/query.component.ts @@ -171,7 +171,6 @@ export class QueryComponent implements OnChanges { return this.dataService.requestMetadata() - console.log('>>> QueryComponent >>> getStatistics', this.selectedDateRange) // get all values from form if(! this.selectedDateRange) return @@ -274,7 +273,7 @@ export class QueryComponent implements OnChanges { { name: 'USA', value: 'USA' }, { name: 'Australia', value: 'AUS' }, { name: 'Canada', value: 'CAN' }, - { name: 'South Africa', value: 'SA' }, + { name: 'South Africa', value: 'ZAF' }, ] diff --git a/src/app/data.service.spec.ts b/src/app/data.service.spec.ts index 3f8a4d6..e9ccf11 100644 --- a/src/app/data.service.spec.ts +++ b/src/app/data.service.spec.ts @@ -617,7 +617,8 @@ describe('DataService', () => { const queryParams = { start: '2022-08-16T00:52:40.000Z', end: '2023-08-16T00:52:40.000Z', - hashtags: 'missingmaps' + hashtags: 'missingmaps', + countries: '' }; service.requestSummary( queryParams ).subscribe({ @@ -630,7 +631,7 @@ describe('DataService', () => { }); const req = httpTestingController.expectOne( - `${service.url}/stats/${queryParams['hashtags']}?startdate=${queryParams['start']}&enddate=${queryParams['end']}` + `${service.url}/stats/${queryParams['hashtags']}?startdate=${queryParams['start']}&enddate=${queryParams['end']}&countries=` ); expect(req.request.method).toBe('GET'); req.flush(summaryResponse); From cb086c333558a75ad40280e1f3c6fdb53beff458 Mon Sep 17 00:00:00 2001 From: jstier Date: Thu, 2 Nov 2023 17:26:26 +0100 Subject: [PATCH 3/3] test: test fragment extraction --- src/app/dashboard/dashboard.component.spec.ts | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/app/dashboard/dashboard.component.spec.ts b/src/app/dashboard/dashboard.component.spec.ts index 312c92f..cd06cc5 100644 --- a/src/app/dashboard/dashboard.component.spec.ts +++ b/src/app/dashboard/dashboard.component.spec.ts @@ -256,7 +256,7 @@ describe('DashboardComponent', () => { ], providers: [ { provide: DataService, useValue: dataServiceSpy }, - { provide: ActivatedRoute, useValue: { fragment: of('hashtags=missingmaps&interval=P1M') } }, + { provide: ActivatedRoute, useValue: { fragment: of('hashtags=missingmaps&interval=P1M&countries=DE,UGA') } }, ] }) .compileComponents(); @@ -284,6 +284,19 @@ describe('DashboardComponent', () => { expect(params).toEqual(expectedParams); }); + it('should get query params from URL fragment', () => { + const fragment = 'start=2020-01-01T00:00:00.000Z&end=2020-12-31T00:00:00.000Z&countries=DE,UGA'; + const expectedParams = { + start: '2020-01-01T00:00:00.000Z', + end: '2020-12-31T00:00:00.000Z', + countries: "DE,UGA" + }; + + const params = component.getQueryParamsFromFragments(fragment); + + expect(params).toEqual(expectedParams); + }); + // it('should call data service to fetch summary data', () => { // const queryParams = { // start: '2022-08-16T00:52:40.000Z',