MOBILE-3926 core: Add Source generic to managers

main
Noel De Martin 2021-11-17 12:31:05 +01:00
parent 2c8ef51130
commit d6d5429ee1
4 changed files with 22 additions and 13 deletions

View File

@ -18,6 +18,7 @@ type SourceConstructor<T extends CoreItemsManagerSource = CoreItemsManagerSource
getSourceId(...args: unknown[]): string; getSourceId(...args: unknown[]): string;
new (...args: unknown[]): T; new (...args: unknown[]): T;
}; };
type SourceConstuctorInstance<T> = T extends { new(...args: unknown[]): infer P } ? P : never;
type InstanceTracking = { instance: CoreItemsManagerSource; references: unknown[] }; type InstanceTracking = { instance: CoreItemsManagerSource; references: unknown[] };
type Instances = Record<string, InstanceTracking>; type Instances = Record<string, InstanceTracking>;
@ -36,14 +37,14 @@ export class CoreItemsManagerSourcesTracker {
* @param constructorArguments Arguments to create a new instance, used to find out if an instance already exists. * @param constructorArguments Arguments to create a new instance, used to find out if an instance already exists.
* @returns Source. * @returns Source.
*/ */
static getOrCreateSource<T extends CoreItemsManagerSource>( static getOrCreateSource<T extends CoreItemsManagerSource, C extends SourceConstructor<T>>(
constructor: SourceConstructor<T>, constructor: C,
constructorArguments: ConstructorParameters<SourceConstructor<T>>, constructorArguments: ConstructorParameters<C>,
): T { ): SourceConstuctorInstance<C> {
const id = constructor.getSourceId(...constructorArguments); const id = constructor.getSourceId(...constructorArguments);
const constructorInstances = this.getConstructorInstances(constructor); const constructorInstances = this.getConstructorInstances(constructor);
return constructorInstances[id]?.instance as T return constructorInstances[id]?.instance as SourceConstuctorInstance<C>
?? this.createInstance(id, constructor, constructorArguments); ?? this.createInstance(id, constructor, constructorArguments);
} }

View File

@ -21,13 +21,13 @@ import { CoreItemsManagerSourcesTracker } from './items-manager-sources-tracker'
/** /**
* Helper to manage a collection of items in a page. * Helper to manage a collection of items in a page.
*/ */
export abstract class CoreItemsManager<Item = unknown> { export abstract class CoreItemsManager<Item = unknown, Source extends CoreItemsManagerSource<Item> = CoreItemsManagerSource<Item>> {
protected source?: { instance: CoreItemsManagerSource<Item>; unsubscribe: () => void }; protected source?: { instance: Source; unsubscribe: () => void };
protected itemsMap: Record<string, Item> | null = null; protected itemsMap: Record<string, Item> | null = null;
protected selectedItem: Item | null = null; protected selectedItem: Item | null = null;
constructor(source: CoreItemsManagerSource<Item>) { constructor(source: Source) {
this.setSource(source); this.setSource(source);
} }
@ -36,7 +36,7 @@ export abstract class CoreItemsManager<Item = unknown> {
* *
* @returns Source. * @returns Source.
*/ */
getSource(): CoreItemsManagerSource<Item> { getSource(): Source {
if (!this.source) { if (!this.source) {
throw new Error('Source is missing from items manager'); throw new Error('Source is missing from items manager');
} }
@ -49,7 +49,7 @@ export abstract class CoreItemsManager<Item = unknown> {
* *
* @param newSource New source. * @param newSource New source.
*/ */
setSource(newSource: CoreItemsManagerSource<Item> | null): void { setSource(newSource: Source | null): void {
if (this.source) { if (this.source) {
CoreItemsManagerSourcesTracker.removeReference(this.source.instance, this); CoreItemsManagerSourcesTracker.removeReference(this.source.instance, this);

View File

@ -26,13 +26,16 @@ import { CoreItemsManagerSource } from './items-manager-source';
/** /**
* Helper class to manage the state and routing of a list of items in a page. * Helper class to manage the state and routing of a list of items in a page.
*/ */
export abstract class CoreListItemsManager<Item = unknown> extends CoreItemsManager<Item> { export abstract class CoreListItemsManager<
Item = unknown,
Source extends CoreItemsManagerSource<Item> = CoreItemsManagerSource<Item>
> extends CoreItemsManager<Item, Source> {
protected pageRouteLocator?: unknown | ActivatedRoute; protected pageRouteLocator?: unknown | ActivatedRoute;
protected splitView?: CoreSplitViewComponent; protected splitView?: CoreSplitViewComponent;
protected splitViewOutletSubscription?: Subscription; protected splitViewOutletSubscription?: Subscription;
constructor(source: CoreItemsManagerSource<Item>, pageRouteLocator: unknown | ActivatedRoute) { constructor(source: Source, pageRouteLocator: unknown | ActivatedRoute) {
super(source); super(source);
this.pageRouteLocator = pageRouteLocator; this.pageRouteLocator = pageRouteLocator;

View File

@ -17,11 +17,16 @@ import { ActivatedRoute } from '@angular/router';
import { CoreNavigator } from '@services/navigator'; import { CoreNavigator } from '@services/navigator';
import { CoreItemsManager } from './items-manager'; import { CoreItemsManager } from './items-manager';
import { CoreItemsManagerSource } from './items-manager-source';
/** /**
* Helper class to manage the state and routing of a swipeable page. * Helper class to manage the state and routing of a swipeable page.
*/ */
export abstract class CoreSwipeItemsManager<Item = unknown> extends CoreItemsManager<Item> { export abstract class CoreSwipeItemsManager<
Item = unknown,
Source extends CoreItemsManagerSource<Item> = CoreItemsManagerSource<Item>
>
extends CoreItemsManager<Item, Source> {
/** /**
* Process page started operations. * Process page started operations.