Stats generic service
This commit is contained in:
parent
0610684e8f
commit
f4ffa08f86
@ -9,7 +9,7 @@ import { IqserEventTarget } from '../utils';
|
||||
* However, some components (e.g. redaction-select, color picker) don't set focus on the input after choosing a value.
|
||||
* Also, other components (e.g. dropdown select) trigger a different action on enter, instead of submit.
|
||||
*
|
||||
* Make sure to remove property type="submit" from the save button and the (submit)="save()" property from the form
|
||||
* Make sure to remove the (submit)="save()" property from the form and to set type="button" on the save button
|
||||
* (otherwise the save request will be triggered twice).
|
||||
* */
|
||||
export abstract class BaseDialogComponent {
|
||||
|
||||
@ -3,3 +3,4 @@ export * from './toaster.service';
|
||||
export * from './error-message.service';
|
||||
export * from './generic.service';
|
||||
export * from './composite-route.guard';
|
||||
export * from './stats.service';
|
||||
|
||||
62
src/lib/services/stats.service.ts
Normal file
62
src/lib/services/stats.service.ts
Normal file
@ -0,0 +1,62 @@
|
||||
import { Inject, Injectable, Injector } from '@angular/core';
|
||||
import { BehaviorSubject, Observable } from 'rxjs';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { tap } from 'rxjs/operators';
|
||||
import { HeadersConfiguration, mapEach, RequiredParam, Validate } from '../utils';
|
||||
|
||||
@Injectable()
|
||||
export abstract class StatsService<E, I = E> {
|
||||
private readonly _http = this._injector.get(HttpClient);
|
||||
private readonly _map = new Map<string, BehaviorSubject<E>>();
|
||||
|
||||
protected constructor(
|
||||
protected readonly _injector: Injector,
|
||||
@Inject('ENTITY_PRIMARY_KEY') protected readonly _primaryKey: string,
|
||||
@Inject('ENTITY_CLASS') private readonly _entityClass: new (entityInterface: I, ...args: unknown[]) => E,
|
||||
@Inject('ENTITY_PATH') protected readonly _defaultModelPath: string,
|
||||
) {}
|
||||
|
||||
@Validate()
|
||||
getFor(@RequiredParam() ids: string[]): Observable<E[]> {
|
||||
const request = this._http.post<I[]>(`/${encodeURI(this._defaultModelPath)}`, ids, {
|
||||
headers: HeadersConfiguration.getHeaders(),
|
||||
observe: 'body',
|
||||
});
|
||||
|
||||
return request.pipe(
|
||||
mapEach(entity => new this._entityClass(entity)),
|
||||
tap(entities => entities.forEach(entity => this.set(entity))),
|
||||
);
|
||||
}
|
||||
|
||||
get(key: string): E {
|
||||
return this._getBehaviourSubject(key).value;
|
||||
}
|
||||
|
||||
set(stats: E): void {
|
||||
if (!this._map.has(this._pluckPrimaryKey(stats))) {
|
||||
this._map.set(this._pluckPrimaryKey(stats), new BehaviorSubject<E>(stats));
|
||||
return;
|
||||
}
|
||||
|
||||
const old = this.get(this._pluckPrimaryKey(stats));
|
||||
if (JSON.stringify(old) !== JSON.stringify(stats)) {
|
||||
this._getBehaviourSubject(this._pluckPrimaryKey(stats)).next(stats);
|
||||
}
|
||||
}
|
||||
|
||||
watch$(key: string): Observable<E> {
|
||||
return this._getBehaviourSubject(key).asObservable();
|
||||
}
|
||||
|
||||
private _pluckPrimaryKey(stats: E): string {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
return stats[this._primaryKey] as string;
|
||||
}
|
||||
|
||||
private _getBehaviourSubject(key: string): BehaviorSubject<E> {
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
return this._map.get(key)!;
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user