src/modules/generic-search/classes/abstract-search-component.ts
Abstract class defining the common properties and methods for the Search Page using the StarkGenericSearchComponent.
OnInit
OnDestroy
Properties |
|
Methods |
|
Accessors |
Public
constructor(genericSearchService: StarkGenericSearchService<SearchResultsType | CriteriaType>, logger: StarkLoggingService, progressService: StarkProgressIndicatorService)
|
||||||||||||||||
Class constructor
Parameters :
|
Protected emitResult | ||||||||
emitResult(result: SearchResultsType[])
|
||||||||
Emit the latest results and optionally keeps a reference to them if the preserveLatestResults option is enabled.
Parameters :
Returns :
void
|
Public ngOnDestroy |
ngOnDestroy()
|
Component lifecycle hook
Returns :
void
|
Public ngOnInit |
ngOnInit()
|
Component lifecycle hook
Returns :
void
|
Public onNew |
onNew()
|
Invoke the genericSearchService.createNew() method
Returns :
void
|
Public onReset | ||||||||
onReset(form: UntypedFormGroup)
|
||||||||
Invoke the genericSearchService.resetSearchState() method and clears the results
Parameters :
Returns :
void
|
Public onSearch | ||||||||
onSearch(formGroup: UntypedFormGroup)
|
||||||||
Invoke the search passing the formGroup's working copy only if the Search formGroup is valid
Parameters :
Returns :
void
|
Public performSearch | ||||||||||
performSearch(searchCriteria: CriteriaType)
|
||||||||||
Invoke the genericSearchService.search() method and emits the results. If no searchCriteria object is passed, then the current form's working copy is used.
Parameters :
Returns :
void
|
Protected showProgress | ||||||||
showProgress(show: boolean)
|
||||||||
Call the progressService show/hide methods in case there is a progressTopic defined
Parameters :
Returns :
void
|
Public updateWorkingCopy | ||||||||
updateWorkingCopy(searchCriteria: CriteriaType)
|
||||||||
Update the current working copy of the searchCriteria
Parameters :
Returns :
void
|
Protected isDirty |
isDirty()
|
Inherited from
AbstractStarkFormComponent
|
Defined in
AbstractStarkFormComponent:51
|
Check whether the working copy is exactly the same as the original copy. Performs a deep comparison between the two objects to determine if they are equivalent.
Returns :
boolean
|
Protected reset |
reset()
|
Inherited from
AbstractStarkFormComponent
|
Defined in
AbstractStarkFormComponent:43
|
Revert the form's working copy back to the original copy (a deep clone copy)
Returns :
void
|
Protected setOriginalCopy | ||||||||||
setOriginalCopy(originalCopy: CriteriaType)
|
||||||||||
Inherited from
AbstractStarkFormComponent
|
||||||||||
Defined in
AbstractStarkFormComponent:35
|
||||||||||
Set the form's original copy to the object passed as parameter (a deep cloned copy). Default:
Parameters :
Returns :
void
|
Protected performSearchOnInit |
Type : boolean
|
Whether a new search should be performed automatically after initialization in case the last search criteria can be fetched from the application state (@ngrx/store) |
Protected preserveLatestResults |
Type : boolean
|
Whether the latest emitted results by the emitResult() method will be kept in the latestResults variable |
Public progressIndicatorConfig |
Type : StarkProgressIndicatorConfig
|
The config of the progress indicator to be shown/hidden when performing the search. |
Public logger |
Type : StarkLoggingService
|
Inherited from
AbstractStarkFormComponent
|
Defined in
AbstractStarkFormComponent:27
|
- The `StarkLoggingService` instance of the application.
|
Public originalCopy |
Type : CriteriaType
|
Inherited from
AbstractStarkFormComponent
|
Defined in
AbstractStarkFormComponent:16
|
The form's original copy (the initial model when the form is pristine) |
Public workingCopy |
Type : CriteriaType
|
Inherited from
AbstractStarkFormComponent
|
Defined in
AbstractStarkFormComponent:21
|
The form's working copy (the current model with the latest changes) |
latestResults |
getlatestResults()
|
The latest search results that have been emitted in the results$ Observable.
Returns :
Readonly | undefined
|
import { ReplaySubject, Subscription } from "rxjs";
import { map, take } from "rxjs/operators";
import { Directive, OnDestroy, OnInit } from "@angular/core";
import { UntypedFormGroup } from "@angular/forms";
import { AbstractStarkFormComponent } from "./abstract-form-component";
import { StarkGenericSearchService } from "./generic-search.service.intf";
import { StarkSearchState } from "../entities";
import { StarkErrorImpl, StarkLoggingService } from "@nationalbankbelgium/stark-core";
import { StarkFormUtil } from "@nationalbankbelgium/stark-ui/src/util";
import {
StarkProgressIndicatorConfig,
StarkProgressIndicatorType,
StarkProgressIndicatorService
} from "@nationalbankbelgium/stark-ui/src/modules/progress-indicator";
/**
* Default progress indicator configuration
*/
const defaultProgressIndicatorConfig: StarkProgressIndicatorConfig = {
topic: "",
type: StarkProgressIndicatorType.SPINNER
};
/**
* Abstract class defining the common properties and methods for the Search Page using the {@link StarkGenericSearchComponent}.
*/
@Directive({})
// eslint-disable-next-line @angular-eslint/directive-class-suffix
export abstract class AbstractStarkSearchComponent<SearchResultsType, CriteriaType>
extends AbstractStarkFormComponent<CriteriaType>
implements OnInit, OnDestroy
{
/**
* @internal
* @ignore
*/
private _latestResults?: Readonly<SearchResultsType[]>;
/**
* @internal
* @ignore
*/
private searchStateSubscription!: Subscription;
/**
* Whether a new search should be performed automatically after initialization in case the last search criteria can be fetched
* from the application state (@ngrx/store)
*/
protected performSearchOnInit: boolean;
/**
* Whether the latest emitted results by the emitResult() method will be kept in the latestResults variable
*/
protected preserveLatestResults: boolean;
/**
* The config of the progress indicator to be shown/hidden when performing the search.
*/
public progressIndicatorConfig: StarkProgressIndicatorConfig;
/**
* Observable that will emit the search results. This Observable is created as soon as the Search Page controller is constructed
* and the first value it emits is an empty array in order to avoid the having undefined values passed down to the subscriber(s).
*/
public results$!: ReplaySubject<SearchResultsType[]>;
/**
* Class constructor
* @param genericSearchService - Service implementing the StarkGenericSearchService interface providing all the necessary methods to search items.
* @param logger - The `StarkLoggingService` instance of the application.
* @param progressService - Service that provides an easy way to change the visibility of a progress indicator.
*/
public constructor(
protected genericSearchService: StarkGenericSearchService<SearchResultsType, CriteriaType>,
logger: StarkLoggingService,
protected progressService: StarkProgressIndicatorService
) {
super(logger);
this.progressIndicatorConfig = defaultProgressIndicatorConfig;
this.performSearchOnInit = true;
this.preserveLatestResults = false;
}
/**
* Component lifecycle hook
*/
public ngOnInit(): void {
// it will re-emit the latest value whenever a new observer subscribes to it
// so an empty array can be emitted as the result$ initial value (to avoid having undefined results)
this.results$ = new ReplaySubject<SearchResultsType[]>(1);
// initially an empty array is emitted
this.emitResult([]);
// if a search was done previously (saved in the Redux state)
// then the search is automatically performed on initialization (only if the performSearchOnInit option is TRUE)
this.searchStateSubscription = this.genericSearchService
.getSearchState()
.pipe(
map((searchState: StarkSearchState<CriteriaType>) => {
if (searchState.hasBeenSearched && this.performSearchOnInit) {
this.performSearch(searchState.criteria);
}
return searchState.criteria;
})
)
.subscribe((searchCriteria: CriteriaType) => {
this.setOriginalCopy(searchCriteria);
});
}
/**
* Component lifecycle hook
*/
public ngOnDestroy(): void {
this.searchStateSubscription.unsubscribe();
}
/**
* Invoke the search passing the formGroup's working copy only if the Search formGroup is valid
* @param formGroup - The 'search' formGroup
*/
public onSearch(formGroup: UntypedFormGroup): void {
if (StarkFormUtil.isFormGroupValid(formGroup)) {
this.performSearch(this.workingCopy);
}
}
/**
* Invoke the genericSearchService.createNew() method
*/
public onNew(): void {
if (typeof this.genericSearchService.createNew !== "undefined") {
this.genericSearchService.createNew();
} else {
throw new StarkErrorImpl(
'AbstractStarkSearchComponent: When StarkGenericSearch component has the "new" button defined, ' +
'the service must have an implementation for "createNew" method.'
);
}
}
/**
* Invoke the genericSearchService.resetSearchState() method and clears the results
* @param form - Form to reset
*/
public onReset(form: UntypedFormGroup): void {
this.genericSearchService.resetSearchState();
StarkFormUtil.setFormChildControlsState(form, ["untouched", "pristine"]);
StarkFormUtil.setFormGroupState(form, ["untouched", "pristine"]);
this.emitResult([]);
}
/**
* Update the current working copy of the searchCriteria
* @param searchCriteria - New value of searchCriteria
*/
public updateWorkingCopy(searchCriteria: CriteriaType): void {
this.workingCopy = searchCriteria;
}
/**
* Invoke the genericSearchService.search() method and emits the results. If no searchCriteria object is passed, then the current
* form's working copy is used.
* @param searchCriteria - Criteria to be used to perform the search
*/
public performSearch(searchCriteria: CriteriaType = this.workingCopy): void {
this.performSearchOnInit = false; // prevent further automatic searches due to the subscription to StarkSearchState changes in NgOnInit
this.showProgress(true);
this.genericSearchService
.search(searchCriteria)
.pipe(
take(1) // this ensures that the observable will be automatically unsubscribed after emitting the value
)
.subscribe(
(result: SearchResultsType[]) => {
this.emitResult(result);
this.showProgress(false);
},
() => {
// hide the progress in case of error
this.showProgress(false);
}
);
}
/**
* The latest search results that have been emitted in the results$ Observable.
*/
public get latestResults(): Readonly<SearchResultsType[]> | undefined {
return this._latestResults;
}
/**
* Call the progressService show/hide methods in case there is a progressTopic defined
* @param show - Whether to show the progress indicator or not
*/
protected showProgress(show: boolean): void {
if (this.progressIndicatorConfig && this.progressIndicatorConfig.topic && this.progressIndicatorConfig.topic !== "") {
if (show) {
this.progressService.show(this.progressIndicatorConfig.topic);
} else {
this.progressService.hide(this.progressIndicatorConfig.topic);
}
}
}
/**
* Emit the latest results and optionally keeps a reference to them if the preserveLatestResults option is enabled.
* @param result - Result to emit
*/
protected emitResult(result: SearchResultsType[]): void {
if (this.preserveLatestResults) {
this._latestResults = result;
}
this.results$.next(result);
}
}