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; }