-
Notifications
You must be signed in to change notification settings - Fork 11
refactor: re-structure of page time range to be query param centric #1514
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
Changes from 18 commits
1de4d4d
9f10747
90aca7d
40f55da
31d4f0f
bdb7a8b
595017a
e70957d
898dc90
0c88198
be3d30f
7f4a4f1
8a9660e
17fa1b3
c03ed28
9680f55
75f5be9
c8f632e
a2e33fc
e542a30
1321830
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,8 @@ | ||
| import { Injectable } from '@angular/core'; | ||
| import { isEmpty, isNil } from 'lodash-es'; | ||
| import { EMPTY, ReplaySubject } from 'rxjs'; | ||
| import { catchError, filter, map, switchMap, take } from 'rxjs/operators'; | ||
| import { ParamMap } from '@angular/router'; | ||
| import { isEmpty, isNil, omit } from 'lodash-es'; | ||
| import { concat, EMPTY, Observable, ReplaySubject } from 'rxjs'; | ||
| import { catchError, distinctUntilChanged, filter, map, switchMap, take } from 'rxjs/operators'; | ||
| import { NavigationService, QueryParamObject } from '../navigation/navigation.service'; | ||
| import { ReplayObservable } from '../utilities/rxjs/rxjs-utils'; | ||
| import { FixedTimeRange } from './fixed-time-range'; | ||
|
|
@@ -16,6 +17,7 @@ import { TimeUnit } from './time-unit.type'; | |
| }) | ||
| export class TimeRangeService { | ||
| private static readonly TIME_RANGE_QUERY_PARAM: string = 'time'; | ||
| private static readonly REFRESH_ON_NAVIGATION: string = 'refresh'; | ||
|
|
||
| private readonly timeRangeSubject$: ReplaySubject<TimeRange> = new ReplaySubject(1); | ||
| private currentTimeRange?: TimeRange; | ||
|
|
@@ -51,31 +53,67 @@ export class TimeRangeService { | |
| } | ||
|
|
||
| public setRelativeRange(value: number, unit: TimeUnit): this { | ||
| return this.setTimeRange(TimeRangeService.toRelativeTimeRange(value, unit)); | ||
| // return this.setTimeRange(TimeRangeService.toRelativeTimeRange(value, unit)); | ||
| return this.setTimeRangeInUrl(TimeRangeService.toRelativeTimeRange(value, unit)); | ||
| } | ||
|
|
||
| public setFixedRange(startTime: Date, endTime: Date): this { | ||
| return this.setTimeRange(TimeRangeService.toFixedTimeRange(startTime, endTime)); | ||
| // return this.setTimeRange(TimeRangeService.toFixedTimeRange(startTime, endTime)); | ||
| return this.setTimeRangeInUrl(TimeRangeService.toFixedTimeRange(startTime, endTime)); | ||
| } | ||
|
|
||
| public refresh(): void { | ||
| this.setTimeRange(this.getCurrentTimeRange()); | ||
| const currentStringTimeRange = this.getCurrentTimeRange().toUrlString(); | ||
| this.applyTimeRangeChange(this.timeRangeFromUrlString(currentStringTimeRange)); | ||
| } | ||
|
|
||
| private getInitialTimeRange(): Observable<TimeRange> { | ||
| return this.navigationService.navigation$.pipe( | ||
| take(1), // Wait for first navigation | ||
| switchMap(activatedRoute => activatedRoute.queryParamMap), // Get the params from it | ||
| take(1), // Only the first set of params | ||
| map(paramMap => paramMap.get(TimeRangeService.TIME_RANGE_QUERY_PARAM)), // Extract the time range value from it | ||
| filter((timeRangeString): timeRangeString is string => !isEmpty(timeRangeString)), // Only valid time ranges | ||
| map(timeRangeString => this.timeRangeFromUrlString(timeRangeString)), | ||
| catchError(() => EMPTY) | ||
| ); | ||
| } | ||
|
|
||
| private getPageTimeRangeChanges(): Observable<TimeRange> { | ||
| return this.navigationService.navigation$.pipe( | ||
| map(activeRoute => activeRoute.snapshot.queryParamMap), | ||
| filter(queryParamMap => !isNil(queryParamMap.get(TimeRangeService.TIME_RANGE_QUERY_PARAM))), | ||
| distinctUntilChanged((prevParamMap, currParamMap) => this.shouldNotUpdateTimeRange(prevParamMap, currParamMap)), | ||
| map(currQueryParamMap => { | ||
| const timeRangeQueryParamString = currQueryParamMap.get(TimeRangeService.TIME_RANGE_QUERY_PARAM); | ||
|
|
||
| return this.timeRangeFromUrlString(timeRangeQueryParamString!); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So when do we want to emit?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No this only emits when we navigate and have a time query param. Drill behaviour still works as expected. |
||
| }) | ||
| ); | ||
| } | ||
|
|
||
| private initializeTimeRange(): void { | ||
| this.navigationService.navigation$ | ||
| .pipe( | ||
| take(1), // Wait for first navigation | ||
| switchMap(activatedRoute => activatedRoute.queryParamMap), // Get the params from it | ||
| take(1), // Only the first set of params | ||
| map(paramMap => paramMap.get(TimeRangeService.TIME_RANGE_QUERY_PARAM)), // Extract the time range value from it | ||
| filter((timeRangeString): timeRangeString is string => !isEmpty(timeRangeString)), // Only valid time ranges | ||
| map(timeRangeString => this.timeRangeFromUrlString(timeRangeString)), | ||
| catchError(() => EMPTY) | ||
| ) | ||
| .subscribe(timeRange => { | ||
| this.setTimeRange(timeRange); | ||
| }); | ||
| concat(this.getInitialTimeRange(), this.getPageTimeRangeChanges()).subscribe(timeRange => { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. one option discussed offline - the two branches of the subscribe basically handle the respective emissions of these two observables. We could do it as two separate subscriptions and it would probably be easier to understand. |
||
| if (!this.timeRangeMatchesCurrentUrl(timeRange)) { | ||
| this.setTimeRangeInUrl(timeRange); | ||
| } else { | ||
| this.applyTimeRangeChange(timeRange); | ||
|
|
||
| const queryParams = this.navigationService.getCurrentActivatedRoute().snapshot.queryParams; | ||
| if (TimeRangeService.REFRESH_ON_NAVIGATION in queryParams) { | ||
| this.navigationService.replaceQueryParametersInUrl(omit(queryParams, TimeRangeService.REFRESH_ON_NAVIGATION)); | ||
| } | ||
| } | ||
| }); | ||
| } | ||
|
|
||
| private shouldNotUpdateTimeRange(prevParamMap: ParamMap, currParamMap: ParamMap): boolean { | ||
| const refreshQueryParam = currParamMap.get(TimeRangeService.REFRESH_ON_NAVIGATION); | ||
|
|
||
| return ( | ||
| prevParamMap.get(TimeRangeService.TIME_RANGE_QUERY_PARAM) === | ||
| currParamMap.get(TimeRangeService.TIME_RANGE_QUERY_PARAM) && isEmpty(refreshQueryParam) | ||
| ); | ||
| } | ||
|
|
||
| public timeRangeFromUrlString(timeRangeFromUrl: string): TimeRange { | ||
|
|
@@ -91,19 +129,24 @@ export class TimeRangeService { | |
| throw new Error(); // Caught in observable | ||
| } | ||
|
|
||
| private setTimeRange(newTimeRange: TimeRange): this { | ||
| private applyTimeRangeChange(newTimeRange: TimeRange): this { | ||
| this.currentTimeRange = newTimeRange; | ||
| this.timeRangeSubject$.next(newTimeRange); | ||
|
|
||
| return this; | ||
| } | ||
|
|
||
| private setTimeRangeInUrl(timeRange: TimeRange): this { | ||
| this.navigationService.addQueryParametersToUrl({ | ||
| [TimeRangeService.TIME_RANGE_QUERY_PARAM]: newTimeRange.toUrlString() | ||
| [TimeRangeService.TIME_RANGE_QUERY_PARAM]: timeRange.toUrlString() | ||
| }); | ||
|
|
||
| return this; | ||
| } | ||
|
|
||
| public setDefaultTimeRange(timeRange: TimeRange): void { | ||
| if (!this.currentTimeRange) { | ||
| this.setTimeRange(timeRange); | ||
| this.setTimeRangeInUrl(timeRange); | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -115,12 +158,22 @@ export class TimeRangeService { | |
| return new FixedTimeRange(startTime, endTime); | ||
| } | ||
|
|
||
| public toQueryParams(startTime: Date, endTime: Date): QueryParamObject { | ||
| const newTimeRange = new FixedTimeRange(startTime, endTime); | ||
|
|
||
| return { | ||
| [TimeRangeService.TIME_RANGE_QUERY_PARAM]: newTimeRange.toUrlString() | ||
| public toQueryParams(timeRange: TimeRange, refreshTimeOnNavigationParam?: boolean): QueryParamObject { | ||
| const queryParams: QueryParamObject = { | ||
| [TimeRangeService.TIME_RANGE_QUERY_PARAM]: timeRange.toUrlString() | ||
| }; | ||
|
|
||
| if (refreshTimeOnNavigationParam) { | ||
| return { ...queryParams, [TimeRangeService.REFRESH_ON_NAVIGATION]: true }; | ||
| } | ||
|
|
||
| return queryParams; | ||
| } | ||
|
|
||
| private timeRangeMatchesCurrentUrl(timeRange: TimeRange): boolean { | ||
| return ( | ||
| this.navigationService.getQueryParameter(TimeRangeService.TIME_RANGE_QUERY_PARAM, '') === timeRange.toUrlString() | ||
| ); | ||
| } | ||
|
|
||
| public isInitialized(): boolean { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove commented code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed thanks, noticed just have i pushed