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

frontend: Fix router event handling in base class #2375

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -318,6 +318,7 @@ export abstract class DataJobsBaseGridComponent
*/
onModelInit(): void {
let initializationFinished = false;
let previousState: RouteState;

this.subscriptions.push(
this.routerService
Expand All @@ -332,21 +333,28 @@ export abstract class DataJobsBaseGridComponent
)
.subscribe((routerState) => {
if (initializationFinished) {
if (!this._areQueryParamsPristine(routerState.state)) {
// check if route state comes from Browser popped state (Browser stack)
if (
(!previousState || previousState.absoluteRoutePath === routerState.state.absoluteRoutePath) &&
!this._areQueryParamsPristine(routerState.state)
) {
this._extractQueryParams(routerState.state);
this._updateUrlStateManager();

// set query params mutation to false, because it's popped state from Browser stack
// set query params mutation to false, because it's Browser popped state
// no need to update the Browser URL, just URLStateManager need to be updated
this.urlStateManager.isQueryParamsStateMutated = false;
} else {
this._updateUrlStateManager(routerState.state);
}

previousState = routerState.state;

return;
}

initializationFinished = true;
previousState = routerState.state;

this._initUrlStateManager(routerState.state);
this._extractQueryParams(routerState.state);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { ArrayElement, CollectionsUtil } from '../../../utils';

import { Replacer, TaurusNavigateAction } from '../../../common';

import { SE_NAVIGATE, SystemEventHandler, SystemEventHandlerClass } from '../../system-events';
import { SE_NAVIGATE, SystemEventHandler, SystemEventHandlerClass, SystemEventNavigatePayload } from '../../system-events';

import { RouterService, RouteState } from '../../router';
import { RouteStateFactory } from '../../router/factory';
Expand All @@ -36,7 +36,7 @@ export class NavigationService {
* ** Intercept SE_NAVIGATE Event and handle (react) on it.
*/
@SystemEventHandler(SE_NAVIGATE)
_navigationSystemEventHandler_(payload: { url: string | string[]; extras?: NavigationExtras }): Promise<boolean> {
_navigationSystemEventHandler_(payload: SystemEventNavigatePayload): Promise<boolean> {
if (CollectionsUtil.isNil(payload)) {
return Promise.resolve(false);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,29 @@
* SPDX-License-Identifier: Apache-2.0
*/

import { NavigationExtras } from '@angular/router';

/**
* ** System Event ID for navigation trigger.
*
* - Send event [BLOCKING]
* - Every Handler should return Promise.
*
* - Payload {url: string | string[], extras?: NavigationExtras}
* - Payload {@link SystemEventNavigatePayload}
*/
export const SE_NAVIGATE = 'SE_Navigate';

/**
* ** System Event ID for location change through {@link @angular/common/Location}.
*
* - Post event [NON-BLOCKING]
* - Every Handler could either consume event as void (return nothing) or return Promise.
* - Execution is in queue using setTimeout of 0.
*
* - Payload {@link SystemEventLocationChangePayload}
*/
export const SE_LOCATION_CHANGE = 'SE_Location_Change';

/**
* ** System Event that could be consumed by Handlers.
* <p>
Expand All @@ -24,3 +37,45 @@ export const SE_NAVIGATE = 'SE_Navigate';
* - Payload {any}
*/
export const SE_ALL_EVENTS = '*';

// events payload types

/**
* ** Payload send whenever {@link SE_NAVIGATE} event is fired.
*/
export interface SystemEventNavigatePayload {
url: string | string[];
extras?: NavigationExtras;
}

/**
* ** Payload post whenever {@link SE_LOCATION_CHANGE} event is fired.
*/
export interface SystemEventLocationChangePayload {
/**
* ** Url in string format.
*
* - e.g. '/pathname/path-param_1/path-param_2?query-param-1=value_1&query-param-2=value_2'
*/
url: string;
/**
* ** Dynamic path params in key-value map format.
*/
params: { [key: string]: string };
/**
* ** Dynamic path params serialized in string format.
*
* - e.g. '/pathname/path-param_1/path-param_2'
*/
paramsSerialized: string;
/**
* ** Dynamic query params in key-value map format.
*/
queryParams: { [key: string]: string };
/**
* ** Dynamic query params serialized in string format.
*
* - e.g. 'query-param-1=value_1&query-param-2=value_2'
*/
queryParamsSerialized: string;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@

export { SystemEventHandler, SystemEventHandlerClass } from './decorator';
export { SystemEventDispatcher } from './dispatcher';
export { SE_NAVIGATE, SE_ALL_EVENTS, SystemEvent, SystemEventFilterExpression, SystemEventComparable } from './event';
export { SystemEvent, SystemEventFilterExpression, SystemEventComparable } from './event';
// export all core system events
export * from './event/models/event.codes';
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import { Location } from '@angular/common';

import { SE_NAVIGATE, SystemEventDispatcher } from '../system-events';
import { SE_LOCATION_CHANGE, SE_NAVIGATE, SystemEventDispatcher } from '../system-events';

export interface StateManagerParamValue {
key: string;
Expand Down Expand Up @@ -84,6 +84,8 @@ export class URLStateManager {

this.isParamsStateMutated = false;

this._notifyForLocationChange();

this.urlLocation.go(this.URL);
}

Expand Down Expand Up @@ -242,6 +244,20 @@ export class URLStateManager {
return paramsMap;
}

/**
* ** Returns params in Map format.
*/
getParamsAsMap(): { [key: string]: string } {
const sortedParams = this.getSortedByPosition(this.params);
const paramsMap = {};

for (const paramsPair of sortedParams) {
paramsMap[paramsPair.key] = paramsPair.value;
}

return paramsMap;
}

/**
* ** Build url from base and provided params.
*/
Expand All @@ -265,4 +281,19 @@ export class URLStateManager {
.sort((p1, p2) => p1[1].position - p2[1].position)
.map((e) => e[1]);
}

private _notifyForLocationChange(): void {
const paramsMap = this.getParamsAsMap();
const paramsSerialized = this.buildUrlWithParams();
const queryParamsMap = this.getQueryParamsAsMap();
const queryParamsSerialized = this.getQueryParamsToString();

SystemEventDispatcher.post(SE_LOCATION_CHANGE, {
url: this.URL,
params: paramsMap ? paramsMap : {},
paramsSerialized: paramsSerialized ? paramsSerialized : '',
queryParams: queryParamsMap ? queryParamsMap : {},
queryParamsSerialized: queryParamsSerialized ? queryParamsSerialized.replace(/^\?/, '') : ''
});
}
}