Entities can have numbers as ids

This commit is contained in:
Adina Țeudan 2022-07-22 10:52:26 +03:00
parent b1f8de6ea1
commit 7875f99a07
5 changed files with 27 additions and 22 deletions

View File

@ -1,7 +1,8 @@
import { IListable } from './listable';
import { Id } from './trackable';
export abstract class Entity<I> implements IListable {
abstract readonly id: string;
abstract readonly id: Id;
abstract readonly routerLink?: string;
abstract readonly searchKey: string;

View File

@ -1,3 +1,5 @@
export type Id = string | number;
export interface ITrackable {
readonly id: string;
readonly id: Id;
}

View File

@ -4,6 +4,7 @@ import { filter, map, startWith, tap } from 'rxjs/operators';
import { IListable } from '../models';
import { GenericService, QueryParam } from '../../services';
import { getLength, List, mapEach, shareDistinctLast, shareLast } from '../../utils';
import { Id } from '../models/trackable';
@Injectable()
/**
@ -47,7 +48,7 @@ export class EntitiesService<I, E extends I & IListable = I & IListable> extends
);
}
getEntityChanged$(entityId: string): Observable<E | undefined> {
getEntityChanged$(entityId: Id): Observable<E | undefined> {
return this._entityChanged$.pipe(
filter(entity => entity.id === entityId),
startWith(this.find(entityId)),
@ -55,7 +56,7 @@ export class EntitiesService<I, E extends I & IListable = I & IListable> extends
);
}
getEntityDeleted$(entityId: string): Observable<E | undefined> {
getEntityDeleted$(entityId: Id): Observable<E | undefined> {
return this._entityDeleted$.pipe(filter(entity => entity.id === entityId));
}
@ -88,7 +89,7 @@ export class EntitiesService<I, E extends I & IListable = I & IListable> extends
}
}
remove(id: string) {
remove(id: Id) {
const entity = this.all.find(item => item.id === id);
if (entity) {
this.#all$.next(this.all.filter(item => item.id !== id));
@ -96,11 +97,11 @@ export class EntitiesService<I, E extends I & IListable = I & IListable> extends
}
}
find(id: string): E | undefined {
find(id: Id): E | undefined {
return this.all.find(entity => entity.id === id);
}
has(id: string): boolean {
has(id: Id): boolean {
return this.all.some(entity => entity.id === id);
}

View File

@ -3,12 +3,13 @@ import { BehaviorSubject, Observable, Subject } from 'rxjs';
import { filter, startWith } from 'rxjs/operators';
import { Entity } from '../listing';
import { RequiredParam, shareLast, Validate } from '../utils';
import { Id } from '../listing/models/trackable';
@Injectable({ providedIn: 'root' })
export abstract class EntitiesMapService<E extends Entity<I>, I> {
protected abstract readonly _primaryKey: string;
protected readonly _map = new Map<string, BehaviorSubject<E[]>>();
protected readonly _map = new Map<Id, BehaviorSubject<E[]>>();
readonly #entityChanged$ = new Subject<E>();
readonly #entityDeleted$ = new Subject<E>();
@ -16,11 +17,11 @@ export abstract class EntitiesMapService<E extends Entity<I>, I> {
return this._map.size === 0;
}
delete(keys: string[]): void {
delete(keys: Id[]): void {
keys.forEach(key => this._map.delete(key));
}
get$(key: string) {
get$(key: Id) {
if (!this._map.has(key)) {
this._map.set(key, new BehaviorSubject<E[]>([]));
}
@ -28,13 +29,13 @@ export abstract class EntitiesMapService<E extends Entity<I>, I> {
return this._getBehaviourSubject(key).asObservable();
}
has(parentId: string) {
has(parentId: Id) {
return this._map.has(parentId);
}
get(key: string): E[];
get(key: string, id: string): E | undefined;
get(key: string, id?: string): E | E[] | undefined {
get(key: Id): E[];
get(key: Id, id: Id): E | undefined;
get(key: Id, id?: Id): E | E[] | undefined {
const value = this._getBehaviourSubject(key)?.value;
if (!id) {
return value ?? [];
@ -42,7 +43,7 @@ export abstract class EntitiesMapService<E extends Entity<I>, I> {
return value?.find(item => item.id === id);
}
set(key: string, entities: E[]): void {
set(key: Id, entities: E[]): void {
if (!this._map.has(key)) {
this._map.set(key, new BehaviorSubject<E[]>(entities));
return entities.forEach(entity => this.#entityChanged$.next(entity));
@ -96,7 +97,7 @@ export abstract class EntitiesMapService<E extends Entity<I>, I> {
}
@Validate()
watch$(@RequiredParam() key: string, @RequiredParam() entityId: string): Observable<E> {
watch$(@RequiredParam() key: Id, @RequiredParam() entityId: Id): Observable<E> {
return this.#entityChanged$.pipe(
filter(entity => entity.id === entityId),
startWith(this.get(key, entityId) as E),
@ -104,17 +105,17 @@ export abstract class EntitiesMapService<E extends Entity<I>, I> {
);
}
watchDeleted$(entityId: string): Observable<E> {
watchDeleted$(entityId: Id): Observable<E> {
return this.#entityDeleted$.pipe(filter(entity => entity.id === entityId));
}
private _pluckPrimaryKey(entity: E): string {
private _pluckPrimaryKey(entity: E): Id {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
return entity[this._primaryKey] as string;
return entity[this._primaryKey] as Id;
}
private _getBehaviourSubject(key: string): BehaviorSubject<E[]> {
private _getBehaviourSubject(key: Id): BehaviorSubject<E[]> {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
return this._map.get(key)!;
}

View File

@ -1,4 +1,4 @@
import { ITrackable } from '../listing/models/trackable';
import { Id, ITrackable } from '../listing/models/trackable';
import { UntypedFormGroup } from '@angular/forms';
import { forOwn, has, isEqual, isPlainObject, transform } from 'lodash-es';
import dayjs, { Dayjs } from 'dayjs';
@ -34,7 +34,7 @@ export function toNumber(str: string): number {
}
export function trackByFactory<T extends ITrackable>() {
return (_index: number, item: T): string => item.id;
return (_index: number, item: T): Id => item.id;
}
export function hasFormChanged(form: UntypedFormGroup, initialFormValue: Record<string, string>): boolean {