-
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 2 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,10 @@ | ||
| import { Injectable } from '@angular/core'; | ||
| import { isEmpty, isNil } from 'lodash-es'; | ||
| import { EMPTY, ReplaySubject } from 'rxjs'; | ||
| import { EMPTY, Observable, ReplaySubject } from 'rxjs'; | ||
| import { catchError, filter, map, switchMap, take } from 'rxjs/operators'; | ||
| import { ApplicationFeature } from '../constants/application-constants'; | ||
| import { FeatureStateResolver } from '../feature/state/feature-state.resolver'; | ||
| import { FeatureState } from '../feature/state/feature.state'; | ||
| import { NavigationService, QueryParamObject } from '../navigation/navigation.service'; | ||
| import { ReplayObservable } from '../utilities/rxjs/rxjs-utils'; | ||
| import { FixedTimeRange } from './fixed-time-range'; | ||
|
|
@@ -22,7 +25,8 @@ export class TimeRangeService { | |
|
|
||
| public constructor( | ||
| private readonly navigationService: NavigationService, | ||
| private readonly timeDurationService: TimeDurationService | ||
| private readonly timeDurationService: TimeDurationService, | ||
| private readonly featureStateResolver: FeatureStateResolver | ||
| ) { | ||
| this.initializeTimeRange(); | ||
| this.navigationService.registerGlobalQueryParamKey(TimeRangeService.TIME_RANGE_QUERY_PARAM); | ||
|
|
@@ -62,16 +66,44 @@ export class TimeRangeService { | |
| this.setTimeRange(this.getCurrentTimeRange()); | ||
| } | ||
|
|
||
| private globalTimeRangeInitialization(): 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 pageTimeRangeInitialization(): Observable<TimeRange> { | ||
| return this.navigationService.navigation$.pipe( | ||
| filter( | ||
| activatedRoute => !isNil(activatedRoute.snapshot.queryParamMap.get(TimeRangeService.TIME_RANGE_QUERY_PARAM)) | ||
Christian862 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| ), | ||
| map(activeRoute => { | ||
| const timeRangeQueryParamString = activeRoute.snapshot.queryParamMap.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$ | ||
| this.featureStateResolver | ||
| .getFeatureState(ApplicationFeature.PageTimeRange) | ||
| .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) | ||
| switchMap(featureState => { | ||
| if (featureState === FeatureState.Enabled) { | ||
| return this.pageTimeRangeInitialization(); | ||
Christian862 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| return this.globalTimeRangeInitialization(); | ||
| }) | ||
| ) | ||
| .subscribe(timeRange => { | ||
| this.setTimeRange(timeRange); | ||
|
|
@@ -115,11 +147,16 @@ export class TimeRangeService { | |
| return new FixedTimeRange(startTime, endTime); | ||
| } | ||
|
|
||
| public toQueryParams(startTime: Date, endTime: Date): QueryParamObject { | ||
| const newTimeRange = new FixedTimeRange(startTime, endTime); | ||
| public toQueryParams(startTime: Date, endTime: Date, timeRangeIfRelative?: TimeRange): QueryParamObject { | ||
| if (timeRangeIfRelative && timeRangeIfRelative instanceof RelativeTimeRange) { | ||
Christian862 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| return { | ||
| [TimeRangeService.TIME_RANGE_QUERY_PARAM]: timeRangeIfRelative.toUrlString() | ||
| }; | ||
| } | ||
| const newFixedTimeRange = new FixedTimeRange(startTime, endTime); | ||
|
|
||
| return { | ||
| [TimeRangeService.TIME_RANGE_QUERY_PARAM]: newTimeRange.toUrlString() | ||
| [TimeRangeService.TIME_RANGE_QUERY_PARAM]: newFixedTimeRange.toUrlString() | ||
| }; | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -26,7 +26,8 @@ const ROUTE_CONFIG: HtRoute[] = [ | |
| icon: IconType.Dashboard, | ||
| label: 'Dashboard' | ||
| }, | ||
| defaultTimeRange: new RelativeTimeRange(new TimeDuration(1, TimeUnit.Hour)) | ||
| defaultTimeRange: new RelativeTimeRange(new TimeDuration(1, TimeUnit.Hour)), | ||
| shouldSavePageTimeRange: true | ||
|
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. we could infer this - up to you. There's some scenarios where we want to specify a route that should save but doesn't define its own time range - if it does define it's own though, we'd always want to save right?
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. Yeah this crossed my mind. Correct, if the route defines it's own, we'd always want to save. However I'm gonna leave it as is for readability - to anyone looking at these route configs without the full picture, I think it'd be easier to understand with this property here. One condition being satisfied based on one property rather than two, is a bit clearer |
||
| }, | ||
| loadChildren: () => import('../home/home.module').then(module => module.HomeModule) | ||
| }, | ||
|
|
@@ -37,7 +38,8 @@ const ROUTE_CONFIG: HtRoute[] = [ | |
| icon: ObservabilityIconType.ApplicationFlow, | ||
| label: 'Application Flow' | ||
| }, | ||
| defaultTimeRange: new RelativeTimeRange(new TimeDuration(1, TimeUnit.Hour)) | ||
| defaultTimeRange: new RelativeTimeRange(new TimeDuration(1, TimeUnit.Hour)), | ||
| shouldSavePageTimeRange: true | ||
| }, | ||
| loadChildren: () => | ||
| import('./application-flow/application-flow-routing.module').then( | ||
|
|
@@ -51,7 +53,8 @@ const ROUTE_CONFIG: HtRoute[] = [ | |
| icon: ObservabilityIconType.Backend, | ||
| label: 'Backends' | ||
| }, | ||
| defaultTimeRange: new RelativeTimeRange(new TimeDuration(1, TimeUnit.Hour)) | ||
| defaultTimeRange: new RelativeTimeRange(new TimeDuration(1, TimeUnit.Hour)), | ||
| shouldSavePageTimeRange: true | ||
| }, | ||
| loadChildren: () => | ||
| import('./backends/backends-routing.module').then(module => module.BackendsRoutingModule) | ||
|
|
@@ -63,7 +66,8 @@ const ROUTE_CONFIG: HtRoute[] = [ | |
| icon: ObservabilityIconType.Service, | ||
| label: 'Services' | ||
| }, | ||
| defaultTimeRange: new RelativeTimeRange(new TimeDuration(1, TimeUnit.Hour)) | ||
| defaultTimeRange: new RelativeTimeRange(new TimeDuration(1, TimeUnit.Hour)), | ||
| shouldSavePageTimeRange: true | ||
| }, | ||
| loadChildren: () => | ||
| import('./services/services-routing.module').then(module => module.ServicesRoutingModule) | ||
|
|
@@ -75,7 +79,8 @@ const ROUTE_CONFIG: HtRoute[] = [ | |
| icon: ObservabilityIconType.Api, | ||
| label: 'Endpoints' | ||
| }, | ||
| defaultTimeRange: new RelativeTimeRange(new TimeDuration(1, TimeUnit.Hour)) | ||
| defaultTimeRange: new RelativeTimeRange(new TimeDuration(1, TimeUnit.Hour)), | ||
| shouldSavePageTimeRange: true | ||
| }, | ||
| loadChildren: () => | ||
| import('./endpoints/endpoint-routing.module').then(module => module.EndpointRoutingModule) | ||
|
|
@@ -95,7 +100,8 @@ const ROUTE_CONFIG: HtRoute[] = [ | |
| icon: IconType.Search, | ||
| label: 'Explorer' | ||
| }, | ||
| defaultTimeRange: new RelativeTimeRange(new TimeDuration(1, TimeUnit.Hour)) | ||
| defaultTimeRange: new RelativeTimeRange(new TimeDuration(1, TimeUnit.Hour)), | ||
| shouldSavePageTimeRange: true | ||
| }, | ||
| loadChildren: () => | ||
| import('./explorer/explorer-routing.module').then(module => module.ExplorerRoutingModule) | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.