2022-07-26 15:30:35 +03:00

81 lines
2.8 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 <code>[FilterService, SearchService, SortingService, ListingService, EntitiesService]</code>
*/
export function listingProvidersFactory(): Provider[];
/**
* This is equivalent to
* @example <code>[{provide: ListingComponent, useExisting: forwardRef(() => component)}, EntitiesService, FilterService, SearchService, SortingService, ListingService]</code>
*/
export function listingProvidersFactory(component: Type<unknown>): Provider[];
/**
* This is equivalent to
* @example <code>[{provide: EntitiesService, useExisting: entitiesService}, {provide: ListingComponent, useExisting: forwardRef(() => component)}, FilterService, SearchService, SortingService, ListingService]</code>
*/
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;
}