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, PrimaryKey extends Id = T['id']> { readonly entitiesService?: Type>; readonly component: Type; } function getEntitiesService, PrimaryKey extends Id = T['id']>( service?: Type>, ): Provider { if (service) { return { provide: EntitiesService, useExisting: service, }; } return EntitiesService; } function getOptions, PrimaryKey extends Id = T['id']>( options?: IListingServiceFactoryOptions | Type, ) { if (typeof options === 'function') { return { component: options, }; } return options; } function getComponent(component: Type) { 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): Provider[]; /** * This is equivalent to * @example * [ * { * provide: EntitiesService, * useExisting: entitiesService * }, * { * provide: ListingComponent, * useExisting: forwardRef(() => component) * }, * FilterService, * SearchService, * SortingService, * ListingService * ] */ export function listingProvidersFactory, PrimaryKey extends Id = T['id']>( options: IListingServiceFactoryOptions, ): Provider[]; export function listingProvidersFactory, PrimaryKey extends Id = T['id']>( args?: IListingServiceFactoryOptions | Type, ): 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; }