2022-12-22 16:26:03 +02:00

113 lines
3.0 KiB
TypeScript

import { FilterService } from '../filtering';
import { SearchService } from '../search';
import { SortingService } from '../sorting';
import { EntitiesService, ListingService } from './services';
import { forwardRef, Provider, Type } from '@angular/core';
import { ListingComponent } from './listing-component.directive';
import { IListable } from './models';
import { Id } from './models/trackable';
export const DefaultListingServices: readonly Provider[] = [FilterService, SearchService, SortingService, ListingService] as const;
export interface IListingServiceFactoryOptions<T extends IListable<PrimaryKey>, PrimaryKey extends Id = T['id']> {
readonly entitiesService?: Type<EntitiesService<T, T>>;
readonly component: Type<unknown>;
}
function getEntitiesService<T extends IListable<PrimaryKey>, PrimaryKey extends Id = T['id']>(
service?: Type<EntitiesService<T, T>>,
): Provider {
if (service) {
return {
provide: EntitiesService,
useExisting: service,
};
}
return EntitiesService;
}
function getOptions<T extends IListable<PrimaryKey>, PrimaryKey extends Id = T['id']>(
options?: IListingServiceFactoryOptions<T> | Type<unknown>,
) {
if (typeof options === 'function') {
return {
component: options,
};
}
return options;
}
function getComponent(component: Type<unknown>) {
return {
provide: ListingComponent,
useExisting: forwardRef(() => component),
};
}
/**
* This is equivalent to
* @example
* [
* FilterService,
* SearchService,
* SortingService,
* ListingService,
* EntitiesService
* ]
*/
export function listingProvidersFactory(): Provider[];
/**
* This is equivalent to
* @example
* [
* {
* provide: ListingComponent,
* useExisting: forwardRef(() => component)
* },
* EntitiesService,
* FilterService,
* SearchService,
* SortingService,
* ListingService
* ]
*/
export function listingProvidersFactory(component: Type<unknown>): Provider[];
/**
* This is equivalent to
* @example
* [
* {
* provide: EntitiesService,
* useExisting: entitiesService
* },
* {
* provide: ListingComponent,
* useExisting: forwardRef(() => component)
* },
* FilterService,
* SearchService,
* SortingService,
* ListingService
* ]
*/
export function listingProvidersFactory<T extends IListable<PrimaryKey>, PrimaryKey extends Id = T['id']>(
options: IListingServiceFactoryOptions<T>,
): Provider[];
export function listingProvidersFactory<T extends IListable<PrimaryKey>, PrimaryKey extends Id = T['id']>(
args?: IListingServiceFactoryOptions<T> | Type<unknown>,
): Provider[] {
const options = getOptions(args);
const services = [...DefaultListingServices];
const entitiesService = getEntitiesService(options?.entitiesService);
services.push(entitiesService);
if (options?.component) {
services.push(getComponent(options.component));
}
return services;
}