libs/ngx-pfe/services/pfe-business-service/business.service.ts
The PfeBusinessService provides functionality, that can be used in the pages to retrieve and store data in the state and to access other parts of the application.
Properties |
|
Methods |
|
Accessors |
constructor(pfeConfigService: PfeConfigurationService, pfeStateService: PfeStateService, pfeNavService: PfeNavigationService, pfeServiceActivatorService: PfeServiceActivatorService, pfeTranslateService: PFETranslateService, logger: NgxLoggerService)
|
|||||||||||||||||||||
Parameters :
|
Async getErrorPage | ||||||
getErrorPage(errorResponse?: HttpErrorResponse)
|
||||||
Parameters :
Returns :
unknown
|
Async getFirstPage |
getFirstPage()
|
Returns :
Promise<string | undefined>
|
getFullState |
getFullState()
|
Returns :
PfeUserInputState
|
Async getNextPage | ||||||
getNextPage(pageNavConfig: PageNavigationConfiguration)
|
||||||
Parameters :
Returns :
unknown
|
getObservableForExpressionKey | ||||||||||||
getObservableForExpressionKey(expression: JsonPathExpression, triggerForUndefined?: boolean, disableDeepEqual?: boolean)
|
||||||||||||
Parameters :
Returns :
Observable<any>
|
getObservableForKey | ||||||||||||
getObservableForKey(key: string, triggerForUndefined?: boolean, disableDeepEqual?: boolean)
|
||||||||||||
Parameters :
Returns :
Observable<any>
|
Public getPageConfigFromRoute | ||||||
getPageConfigFromRoute(activatedRoute: ActivatedRoute)
|
||||||
Parameters :
Returns :
PAGE_CONFIG_TYPE
|
Async getPageConfiguration | ||||||
getPageConfiguration(pageID: string)
|
||||||
Parameters :
Returns :
Promise<PageConfig | undefined>
|
Async getPreviousPage | ||||||
getPreviousPage(pageNavConfig: PageNavigationConfiguration)
|
||||||
Parameters :
Returns :
unknown
|
getValue | ||||||
getValue(key: string)
|
||||||
Returns previously stored data by its key.
Parameters :
Returns :
any
|
getValueByExpression | ||||||
getValueByExpression(jsonPathExpression: string)
|
||||||
Parameters :
Returns :
any
|
Public Async hasConfig |
hasConfig()
|
Returns :
unknown
|
Async navigateBack |
navigateBack()
|
Returns :
Promise<PageConfig | undefined>
|
Async navigateNext | ||||||
navigateNext(ignorePageStatus?: boolean)
|
||||||
Parameters :
Returns :
Promise<PageConfig | undefined>
|
Async navigateToErrorPage | ||||||
navigateToErrorPage(errorResponse?: HttpErrorResponse)
|
||||||
Parameters :
Returns :
unknown
|
Async navigateToPage |
navigateToPage(pageId: string, triggerLeaveActions?: boolean)
|
Returns :
unknown
|
Public ngOnDestroy |
ngOnDestroy()
|
Returns :
void
|
restoreState |
restoreState()
|
Returns :
Promise<any>
|
Public setPageFormIdsToStaleState | ||||||
setPageFormIdsToStaleState(formIds: string[])
|
||||||
setPageFormIds to stale state
Parameters :
Returns :
void
|
setPageStatus | ||||||
setPageStatus(pageStatus: boolean)
|
||||||
Sets the validity status of the current page. When a page is opened it is considered invalid. This will prevent the navigation. Once the page is valid, navigation will be allowed.
Parameters :
Returns :
void
|
storeValue |
storeValue(key: string, value: any)
|
Returns :
void
|
storeValueByExpression | |||||||||
storeValueByExpression(expression: JsonPathExpression, value: any)
|
|||||||||
Parameters :
Returns :
void
|
Async triggerServiceActivators | |||||||||
triggerServiceActivators(pageId: string, hook?: ServiceActivatorHook)
|
|||||||||
Triggers the service activators for a given page and action. {string} pageId the pageId whose service activators will be triggered {ServiceActivatorHook} hook triggers onEnter or onLeave service activators, default is onEnter.
Parameters :
Returns :
any
|
Async triggerSingleServiceActivator | ||||||||||||
triggerSingleServiceActivator(serviceCallInput: string | NavServiceActivatorConfig, httpErrorHandler?: HttpErrorHandler)
|
||||||||||||
Triggers a specific service activator. Either a service activator configuration or just its id is given as input. If the service activator id is provided, the service activator configuration is extracted from the current page configuration or the global config. It returns the HttpResponse in a Promise for service activators that are NOT marked as async (flow async) Error responses are also returned by rejecting the Promise. It is advisable to use the disableErrorPageNavigation flag for service activators that are called via code. Otherwise the currently active page will be left and a navigation to the error page is done.
Parameters :
Returns :
Promise<HttpResponse | undefined>
a Promise with the HttpResponse or HTTPError |
Public currentPageId$ |
Type : BehaviorSubject<string | undefined>
|
Default value : this.pfeNavService.currentPageId$
|
Public pageStatus$ |
Type : BehaviorSubject<boolean>
|
Default value : this.pfeNavService.pageStatus$
|
Public serviceActivatorCallInProgressDetails$ |
Type : Observable<NavServiceActivatorConfig[]>
|
Default value : this.pfeServiceActivatorService.serviceActivatorCallInProgressDetails$
|
serviceActivatorCallInProgress$ |
getserviceActivatorCallInProgress$()
|
Set to true, when a navigation or network call (service activator call) is currently running.
Returns :
BehaviorSubject<boolean>
|
errorMessage$ |
geterrorMessage$()
|
Returns :
Observable<string | undefined>
|
import { NgxLoggerService } from '@allianz/ngx-logger';
import { HttpErrorResponse, HttpResponse } from '@angular/common/http';
import { Injectable, OnDestroy } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { BehaviorSubject, Observable, Subject, combineLatest } from 'rxjs';
import { first, map, takeUntil } from 'rxjs/operators';
import { PFETranslateService } from '../../i18n/pfe-translate.service';
import { JsonPathExpression } from '../../models/jsonpath-expression-type.model';
import { PageNavigationConfiguration, ServiceActivatorHook } from '../../models/navigation-config.model';
import { PageConfig } from '../../models/ngx-pfe-page-config.model';
import { PfeUserInputState } from '../../models/pfe-state/user-input-state.model';
import { NavServiceActivatorConfig } from '../../pfe-service-activator/service/service-activator.model';
import { HttpErrorHandler, PfeServiceActivatorService } from '../../pfe-service-activator/service/service-activator.service';
import { PfeConfigurationService } from '../pfe-config-service/config-service.service';
import { PfeNavigationService } from '../pfe-navigation-service/navigation.service';
import { PfeStateService } from '../pfe-state-service/state.service';
export const PAGE_CONFIG_ROUTE_ATTRIBUTE_NAME = 'pageConfig';
/**
* The PfeBusinessService provides functionality, that can be used in the pages to retrieve and store data
* in the state and to access other parts of the application.
*
* @export
*/
@Injectable()
// eslint-disable-next-line @typescript-eslint/naming-convention
export class PfeBusinessService<PAGE_CONFIG_TYPE extends PageConfig = PageConfig> implements OnDestroy {
public currentPageId$: BehaviorSubject<string | undefined> = this.pfeNavService.currentPageId$;
public pageStatus$: BehaviorSubject<boolean> = this.pfeNavService.pageStatus$;
/**
* Signals if the pfe is busy with:
*
* - A service activator call
* - An action that is tied to a navigation
* - A navigation itself
*
* For example, this can be used to show a loading animation in an app for those events.
*/
public busy$: Observable<boolean> = combineLatest([
this.pfeServiceActivatorService.serviceActivatorCallInProgress$,
this.pfeNavService.navigationInProgress$,
]).pipe(map(([serviceActivator, navigation]) => serviceActivator || navigation));
public serviceActivatorCallInProgressDetails$: Observable<NavServiceActivatorConfig[]> =
this.pfeServiceActivatorService.serviceActivatorCallInProgressDetails$;
private componentDestroyed$ = new Subject<void>();
private _errorMessageSubject$ = new BehaviorSubject<string | undefined>(undefined);
private _errorMessage$: Observable<string | undefined> = this._errorMessageSubject$.asObservable();
private errorMessageDisplayInitialized = false;
constructor(
private pfeConfigService: PfeConfigurationService,
private pfeStateService: PfeStateService,
private pfeNavService: PfeNavigationService,
private pfeServiceActivatorService: PfeServiceActivatorService,
private pfeTranslateService: PFETranslateService,
private logger: NgxLoggerService
) {}
/**
* Set to true, when a navigation or network call (service activator call) is currently running.
*/
get serviceActivatorCallInProgress$(): BehaviorSubject<boolean> {
return this.pfeServiceActivatorService.serviceActivatorCallInProgress$;
}
/**
* @deprecated This will be moved to a separate optional service
*/
public get errorMessage$(): Observable<string | undefined> {
if (!this.errorMessageDisplayInitialized) {
this.initializeValidationDisplay();
this.errorMessageDisplayInitialized = true;
}
return this._errorMessage$;
}
public async hasConfig() {
return (await this.pfeConfigService.getConfig()) !== undefined;
}
async getErrorPage(errorResponse?: HttpErrorResponse) {
return await this.pfeNavService.getErrorPage(errorResponse);
}
async getFirstPage(): Promise<string | undefined> {
return await this.pfeNavService.getFirstPage();
}
async navigateNext(ignorePageStatus?: boolean): Promise<PageConfig | undefined> {
if (!ignorePageStatus && !this.pfeNavService.pageStatus$.value) {
return;
}
return this.pfeNavService.navigateNext();
}
async navigateBack(): Promise<PageConfig | undefined> {
return this.pfeNavService.navigateBack();
}
async navigateToPage(pageId: string, triggerLeaveActions?: boolean) {
return await this.pfeNavService.navigateToPageId(pageId, triggerLeaveActions);
}
async navigateToErrorPage(errorResponse?: HttpErrorResponse) {
return await this.pfeNavService.navigate(await this.pfeNavService.getErrorPage(errorResponse));
}
async getNextPage(pageNavConfig: PageNavigationConfiguration) {
const pageID = await this.pfeNavService.getNextPage(pageNavConfig);
return pageID;
}
async getPreviousPage(pageNavConfig: PageNavigationConfiguration) {
const pageID = await this.pfeNavService.getPreviousPage(pageNavConfig);
return pageID;
}
async getPageConfiguration(pageID: string): Promise<PageConfig | undefined> {
return await this.pfeConfigService.getPageConfiguration(pageID);
}
/**
* Sets the validity status of the current page.
* When a page is opened it is considered invalid.
* This will prevent the navigation.
* Once the page is valid, navigation will be allowed.
*/
setPageStatus(pageStatus: boolean): void {
this.pfeNavService.pageStatus$.next(pageStatus);
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
storeValue(key: string, value: any) {
this.pfeStateService.storeValue(key, value);
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
storeValueByExpression(expression: JsonPathExpression, value: any) {
this.pfeStateService.storeValueByExpression(expression, value);
}
/**
* Returns previously stored data by its key.
*
* @param key
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
getValue(key: string): any {
return this.pfeStateService.getValue(key);
}
/**
* {@link PfeStateService.getObservableForKey}
*
* @param key
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
getObservableForKey(key: string, triggerForUndefined?: boolean, disableDeepEqual?: boolean): Observable<any> {
return this.pfeStateService.getObservableForKey(key, triggerForUndefined, disableDeepEqual);
}
/**
* {@link PfeStateService.getObservableForExpressionKey}
*
* @param key
*/
getObservableForExpressionKey(
expression: JsonPathExpression,
triggerForUndefined?: boolean,
disableDeepEqual?: boolean
// eslint-disable-next-line @typescript-eslint/no-explicit-any
): Observable<any> {
return this.pfeStateService.getObservableForExpressionKey(expression, triggerForUndefined, disableDeepEqual);
}
getValueByExpression(jsonPathExpression: string) {
return this.pfeStateService.getStateValueByExpression(jsonPathExpression);
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
restoreState(): Promise<any> {
return this.pfeStateService.automaticallyRestoreState();
}
getFullState(): PfeUserInputState {
return this.pfeStateService.getFullState();
}
/**
* Triggers the service activators for a given page and action.
*
* {string} pageId the pageId whose service activators will be triggered
* {ServiceActivatorHook} hook triggers onEnter or onLeave service activators, default is onEnter.
*/
async triggerServiceActivators(pageId: string, hook?: ServiceActivatorHook) {
const pageConfig: PageNavigationConfiguration | undefined = await this.pfeConfigService.getPageNavigationConfiguration(pageId);
if (!pageConfig) {
return;
}
try {
const serviceActivators =
hook === ServiceActivatorHook.LEAVE ? pageConfig.onPageLeaveServiceActivators : pageConfig.onPageEnterServiceActivators;
if (serviceActivators) {
await this.pfeServiceActivatorService.spreadWithGlobalServiceActivatorConfig(serviceActivators);
await this.pfeServiceActivatorService.handleServiceActivators(serviceActivators, pageConfig.executeServiceActivatorsSync);
await this.pfeServiceActivatorService.waitForAsyncServiceActivators(pageConfig.pageId);
} else {
throw new Error('Could not determine service activators to be triggered.');
}
} catch (error) {
// Error handling is done in showErrorPage
}
}
/**
* Triggers a specific service activator. Either a service activator configuration or just its id is given as input.
* If the service activator id is provided, the service activator configuration is extracted from
* the current page configuration or the global config.
*
* It returns the HttpResponse in a Promise for service activators that are NOT marked as async (flow async)
* Error responses are also returned by rejecting the Promise.
*
* It is advisable to use the disableErrorPageNavigation flag for service activators that are called via code.
* Otherwise the currently active page will be left and a navigation to the error page is done.
*
* @param serviceCallInput the id of the service activator to be triggered or a service activator configuration
* @param httpErrorHandler an optional custom callback function to receive an information in case any error
* @returns a Promise with the HttpResponse or HTTPError
*/
async triggerSingleServiceActivator(
serviceCallInput: string | NavServiceActivatorConfig,
httpErrorHandler?: HttpErrorHandler
// eslint-disable-next-line @typescript-eslint/no-explicit-any
): Promise<HttpResponse<any> | undefined> {
const pageConfig: PageNavigationConfiguration | undefined = await this.pfeConfigService.getPageNavigationConfiguration(
this.pfeNavService.currentPageId$.value
);
let serviceActivator: NavServiceActivatorConfig | undefined;
if (typeof serviceCallInput === 'string') {
if (!pageConfig) {
return;
}
const globalConfig = await this.pfeConfigService.getConfig();
// So we are inside a page, fine!
if (pageConfig.serviceActivators && pageConfig.serviceActivators[serviceCallInput]) {
serviceActivator = pageConfig.serviceActivators[serviceCallInput];
} else if (globalConfig.navConfiguration.serviceActivators) {
// Ok, so the page has no service activator, lets check in global cfg
serviceActivator = globalConfig.navConfiguration.serviceActivators[serviceCallInput];
}
if (!serviceActivator) {
// eslint-disable-next-line max-len
this.logger.error(
`This serviceCallId "${serviceCallInput}" does not exist. Available option that you have from the configuration: `,
pageConfig.serviceActivators,
globalConfig.navConfiguration.serviceActivators
);
return;
}
} else {
serviceActivator = serviceCallInput;
}
const serviceActivators = [serviceActivator];
await this.pfeServiceActivatorService.spreadWithGlobalServiceActivatorConfig(serviceActivators);
const response = await this.pfeServiceActivatorService.handleServiceActivators(
serviceActivators,
pageConfig?.executeServiceActivatorsSync,
httpErrorHandler
);
if (pageConfig) {
await this.pfeServiceActivatorService.waitForAsyncServiceActivators(pageConfig.pageId);
}
if (Array.isArray(response)) {
// As only one service activator is triggered, there is only 1 response:
return response[0];
} else {
// This will happen if a sequential execution is active
return response;
}
}
public getPageConfigFromRoute(activatedRoute: ActivatedRoute): PAGE_CONFIG_TYPE {
return activatedRoute.snapshot.data[PAGE_CONFIG_ROUTE_ATTRIBUTE_NAME];
}
/**
* setPageFormIds to stale state
* @param formIds
*/
public setPageFormIdsToStaleState(formIds: string[]) {
this.pfeStateService.setStateIds(formIds);
}
public ngOnDestroy() {
this.componentDestroyed$.next();
this.componentDestroyed$.complete();
}
private async initializeValidationDisplay() {
const errorMessageKey = await this.pfeConfigService.getErrorMessageKey();
// set initial state of the error key to undefined
this.storeValue(errorMessageKey, undefined);
this.getObservableForKey(errorMessageKey, true)
.pipe(takeUntil(this.componentDestroyed$))
.subscribe((message) => {
if (message) {
this.pfeTranslateService
.get(message as string)
.pipe(first())
.subscribe((translatedMessage: string) => {
this._errorMessageSubject$.next(translatedMessage);
});
} else {
this._errorMessageSubject$.next(undefined);
}
});
}
// TODO: Add getAppConfiguration
}