@smallpearl/ngx-helper 0.33.8 → 0.33.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -32,6 +32,7 @@ declare class LoadRequest {
32
32
  type StateProps = {
33
33
  allEntitiesLoaded: boolean;
34
34
  loading: boolean;
35
+ loaded: boolean;
35
36
  };
36
37
  /**
37
38
  * An abstract class that you can use wherever you would like to load entities
@@ -165,6 +166,11 @@ export declare abstract class SPPagedEntityLoader<TEntity extends {
165
166
  * @returns
166
167
  */
167
168
  loading(): boolean;
169
+ /**
170
+ * Boolean indicates whether the loader has completed at least one load
171
+ * operation.
172
+ */
173
+ loaded(): boolean;
168
174
  /**
169
175
  * Returns the endpoint URL if the loader was created with an endpoint.
170
176
  * If the loader was created with a loader function, an empty string is
@@ -44,6 +44,7 @@ class LoadRequest {
44
44
  const DEFAULT_STATE_PROPS = {
45
45
  allEntitiesLoaded: false,
46
46
  loading: false,
47
+ loaded: false
47
48
  };
48
49
  // Default paginator implementation. This can handle dynamic-rest and DRF
49
50
  // native pagination schemes. It also has a fallback to handle response conists
@@ -324,6 +325,13 @@ class SPPagedEntityLoader {
324
325
  loading() {
325
326
  return this.store.query((state) => state.loading);
326
327
  }
328
+ /**
329
+ * Boolean indicates whether the loader has completed at least one load
330
+ * operation.
331
+ */
332
+ loaded() {
333
+ return this.store.query((state) => state.loaded);
334
+ }
327
335
  /**
328
336
  * Returns the endpoint URL if the loader was created with an endpoint.
329
337
  * If the loader was created with a loader function, an empty string is
@@ -480,6 +488,7 @@ class SPPagedEntityLoader {
480
488
  ...state,
481
489
  allEntitiesLoaded: !this.hasMore() && !this.searchParamValue,
482
490
  loading: false,
491
+ loaded: true
483
492
  })));
484
493
  }));
485
494
  }
@@ -1 +1 @@
1
- {"version":3,"file":"smallpearl-ngx-helper-entities.mjs","sources":["../../../../projects/smallpearl/ngx-helper/entities/src/paged-loader.ts","../../../../projects/smallpearl/ngx-helper/entities/smallpearl-ngx-helper-entities.ts"],"sourcesContent":["import {\n HttpClient,\n HttpContext,\n HttpContextToken,\n HttpParams,\n} from '@angular/common/http';\nimport { computed, Directive, inject, input } from '@angular/core';\nimport { createStore, setProps, withProps } from '@ngneat/elf';\nimport { getAllEntities, getEntitiesCount, getEntity, upsertEntities, withEntities } from '@ngneat/elf-entities';\nimport { getPaginationData, setPage, skipWhilePageExists, updatePaginationData, withPagination } from '@ngneat/elf-pagination';\nimport { SP_MAT_ENTITY_LIST_CONFIG, SPMatEntityListPaginator, SPPageParams } from '@smallpearl/ngx-helper/mat-entity-list';\nimport { capitalize } from 'lodash';\nimport { plural } from 'pluralize';\nimport {\n distinctUntilChanged,\n filter,\n finalize,\n Observable,\n of,\n Subject,\n Subscription,\n switchMap,\n tap\n} from 'rxjs';\n\n/**\n * A type representing an entity loader function that takes page number,\n * page size, and an optional search value and returns an Observable of\n * the response. This is similar the http.get() method of HttpClient but\n * with pagination parameters. The return value is deliberately kept generic\n * (Observable<any>) to allow flexibility in the response type. This reponse\n * will be parsed by the provided paginator's parseRequestResponse() method.\n * So as long as the function return type and paginator are compatible,\n * any response type can be handled.\n *\n * Ideally the response should contain the total number of entities available\n * at the remote and the array of entities for the requested page.\n */\nexport type SPEntityLoaderFn = (\n page: number,\n pageSize: number,\n searchValue: string | undefined\n) => Observable<any>;\n\n/**\n * Represents a request to load entities from the remote. This is used to\n * compare two requests to determine if they are equal. This is useful to\n * prevent duplicate requests being sent to the remote.\n */\nclass LoadRequest {\n constructor(\n public endpoint: string | SPEntityLoaderFn,\n public pageNumber: number,\n public searchStr: string | undefined,\n public force = false\n ) {}\n\n // Returns true if two LoadRequest objects are equal and this object's\n // 'force' is not set to true.\n isEqualToAndNotForced(prev: LoadRequest): boolean {\n // console.log(\n // `isEqualToAndNotForced - ${this.endpoint}, ${this.params.toString()} ${\n // this.force\n // }, other: ${prev.endpoint}, ${prev.params.toString()}, ${prev.force}`\n // );\n return this.force\n ? false\n : (typeof this.endpoint === 'function' ||\n this.endpoint.localeCompare(prev.endpoint as string) === 0) &&\n this.pageNumber === prev.pageNumber &&\n this.searchStr === prev.searchStr;\n }\n}\n\ntype StateProps = {\n allEntitiesLoaded: boolean;\n loading: boolean;\n};\n\nconst DEFAULT_STATE_PROPS: StateProps = {\n allEntitiesLoaded: false,\n loading: false,\n}\n\n// Default paginator implementation. This can handle dynamic-rest and DRF\n// native pagination schemes. It also has a fallback to handle response conists\n// of an array of entities.\nclass DefaultPaginator implements SPMatEntityListPaginator {\n getRequestPageParams(\n endpoint: string,\n page: number,\n pageSize: number\n ): SPPageParams {\n return {\n page: page + 1,\n pageSize,\n };\n }\n\n parseRequestResponse<\n TEntity extends { [P in IdKey]: PropertyKey },\n IdKey extends string = 'id'\n >(\n entityName: string,\n entityNamePlural: string,\n endpoint: string,\n params: SPPageParams,\n resp: any\n ) {\n if (Array.isArray(resp)) {\n return {\n total: resp.length,\n entities: resp,\n };\n }\n\n if (typeof resp === 'object') {\n const keys = Object.keys(resp);\n // Handle dynamic-rest sideloaded response\n // Rudimentary sideloaded response support. This should work for most\n // of the sideloaded responses where the main entities are stored\n // under the plural entity name key and resp['meta'] object contains\n // the total count.\n if (\n keys.includes(entityNamePlural) &&\n Array.isArray(resp[entityNamePlural])\n ) {\n let total = resp[entityNamePlural].length;\n if (\n keys.includes('meta') &&\n typeof resp['meta'] === 'object' &&\n typeof resp['meta']['total'] === 'number'\n ) {\n total = resp['meta']['total'];\n }\n return {\n total,\n entities: resp[entityNamePlural],\n };\n }\n\n // Handle django-rest-framework style response\n if (keys.includes('results') && Array.isArray(resp['results'])) {\n let total = resp['results'].length;\n if (keys.includes('count') && typeof resp['count'] === 'number') {\n total = resp['count'];\n }\n return {\n total,\n entities: resp['results'],\n };\n }\n\n // Finally, look for \"items\" key\n if (keys.includes('items') && Array.isArray(resp['items'])) {\n return {\n total: resp['items'].length,\n entities: resp['items'],\n };\n }\n }\n\n return {\n total: 0,\n entities: [],\n };\n }\n}\n\n/**\n * An abstract class that you can use wherever you would like to load entities\n * from a remote endpoint in a paged manner. Entities can be loaded in one of\n * two ways:\n *\n * 1. By providing an entityLoaderFn that takes an endpoint and HttpParams\n * and returns a Observable of entities.\n * 2. Or by providing a URL and using the default loader that uses HttpClient\n * to load entities.\n * This class uses RxJS to manage the loading of entities and provides\n * signals to track the loading state, entity count, page index, page size,\n * and whether more entities are available to load.\n *\n * How to use this class:\n *\n * 1. Dervice your component from SPPagedEntityLoader.\n * 2. After your component is initialized, call the startLoader() method to\n * get the component going. This sets up the necessary subscriptions to\n * listen for load requests. Load requests are triggered by calling the\n * loadPage() or loadNextPage() methods.\n * 3. If your component supports infinite scrolling, call loadMoreEntities()\n * method to load the next page of entities when it detects a scroll event.\n * 4. If you component needs to load a specific page (via a pagination control),\n * call the loadPage(pageNumber) method to load the specified page.\n * 5. Entities are stored in an internal entities store which is an @ngneat/elf\n * store. You can subscribe to the store's query to get the list of entities.\n * 6. When your component is destroyed, call the stopLoader() method to clean up\n * internal subscriptions.\n *\n * The class is decorated with Angular's @Directive decorator so that we can\n * use signals for the input properties and dependency injection for HttpClient.\n * There are no abstract methods as such, but the class is meant to be extended\n * by your component to provide the necessary configuration via input properties.\n * This is why it is declared as abstract.\n */\n@Directive({\n selector: '**spPagedEntityLoader**',\n})\nexport abstract class SPPagedEntityLoader<\n TEntity extends { [P in IdKey]: PropertyKey },\n IdKey extends string = 'id'\n> {\n // We cache the entities that we fetch from remote here. Cache is indexed\n // by the endpoint. Each endpoint also keeps a refCount, which is incremented\n // for each instance of the component using the same endpoint. When this\n // refcount reaches 0, the endpoint is removed from the cache.\n //\n // This mechanism is to suppress multiple fetches from the remote from the\n // same endpoint as that can occur if a form has multiple instances of\n // this component with the same url.\n static _entitiesCache = new Map<string, { refCount: number; resp: any }>();\n // cache keys for this instance\n cacheKeys = new Set<string>();\n\n // Current search parameter value. This is used to load entities\n // matching the search string.\n searchParamValue: string | undefined;\n\n //** REQUIRED ATTRIBUTES **//\n /**\n * Entity name, that is used to form the \"New { item }\" menu item if\n * inlineNew=true. This is also used as the key of the object in GET response\n * if the reponse JSON is an object (sideloaded response), where the values\n * are stored indexed by the server model name. For eg:-\n *\n * {\n * 'customers': [\n * {...},\n * {...},\n * {...},\n * ]\n * }\n */\n entityName = input.required<string>();\n url = input.required<string | SPEntityLoaderFn>();\n\n //** OPTIONAL ATTRIBUTES **//\n // Number of entities to be loaded per page from the server. This will be\n // passed to PagedEntityLoader to load entities in pages. Defaults to 50.\n // Adjust this accordingly based on the average size of your entities to\n // optimize server round-trips and memory usage.\n pageSize = input<number>(50);\n\n // Paginator for the remote entity list. This is used to determine the\n // pagination parameters for the API request. If not specified, the global\n // paginator specified in SPMatEntityListConfig will be used. If that too is\n // not specified, a default paginator will be used. Default paginator can\n // handle DRF native PageNumberPagination and dynamic-rest style pagination.\n paginator = input<SPMatEntityListPaginator>();\n\n // Search parameter name to be used in the HTTP request.\n // Defaults to 'search'. That is when a search string is specified and\n // the entire entity list has not been fetched, a fresh HTTP request is made\n // to the remote server with `?<searchParamName>=<search string>` parameter.\n searchParamName = input<string>('search');\n\n // Entity idKey, if idKey is different from the default 'id'.\n idKey = input<string>('id');\n\n // Plural entity name, used when grouping options. If not specified, it is\n // derived by pluralizing the entityName.\n pluralEntityName = input<string | undefined>(undefined); // defaults to pluralized entityName\n\n httpReqContext = input<\n [[HttpContextToken<any>, any]] | [HttpContextToken<any>, any] | undefined\n >(undefined); // defaults to empty context\n\n // Parameters to be added to the HTTP request to retrieve data from\n // remote. This won't be used if `loadFromRemoteFn` is specified.\n httpParams = input<HttpParams | undefined>(undefined); // defaults to empty params\n\n // Mechanism to default pageSize to last entities length.\n protected loadRequest$ = new Subject<LoadRequest>();\n protected sub$: Subscription | undefined;\n protected _pageSize = computed<number>(() =>\n this.pageSize() ? this.pageSize() : 50\n );\n\n protected _pluralEntityName = computed<string>(() => {\n const pluralEntityName = this.pluralEntityName();\n return pluralEntityName ? pluralEntityName : plural(this.entityName());\n });\n\n protected _capitalizedEntityName = computed<string>(() =>\n capitalize(this.entityName())\n );\n\n protected _httpReqContext = computed(() => {\n let reqContext = this.httpReqContext();\n const context = new HttpContext();\n if (reqContext && Array.isArray(reqContext)) {\n if (reqContext.length == 2 && !Array.isArray(reqContext[0])) {\n // one dimensional array of a key, value pair.\n context.set(reqContext[0], reqContext[1]);\n } else {\n reqContext.forEach(([k, v]) => context.set(k, v));\n }\n }\n return context;\n });\n\n entityListConfig = inject(SP_MAT_ENTITY_LIST_CONFIG, {\n optional: true,\n });\n protected _paginator = computed<SPMatEntityListPaginator>(() => {\n const paginator = this.paginator();\n const entityListConfigPaginator = this.entityListConfig\n ? (this.entityListConfig.paginator as SPMatEntityListPaginator)\n : undefined;\n return paginator\n ? paginator\n : entityListConfigPaginator\n ? entityListConfigPaginator\n : new DefaultPaginator();\n });\n\n // We create it here so that store member variable will have the correct\n // type. Unfortunately elf doesn't have a simple generic type that we can\n // use to declare the type of the store and then initialize it later.\n // We will recreate it in the constructor to have the correct idKey.\n protected store = createStore(\n { name: Math.random().toString(36).slice(2) },\n withEntities<TEntity, IdKey>({ idKey: 'id' as IdKey }),\n withProps<StateProps>(DEFAULT_STATE_PROPS),\n withPagination({\n initialPage: 0,\n })\n );\n\n protected http = inject(HttpClient);\n\n constructor() {}\n\n /**\n * Starts listening for load requests and processes them. Call this from your\n * component's ngOnInit() or ngAfterViewInit() method.\n */\n startLoader() {\n // Recreate store with the correct idKey. We have to do this after\n // the idKey is available from the constructor argument.\n const entities = this.store.query(getAllEntities());\n this.store = createStore(\n { name: Math.random().toString(36).slice(2) },\n withEntities<TEntity, IdKey>({ initialValue: entities, idKey: this.idKey() as IdKey }),\n withProps<StateProps>(DEFAULT_STATE_PROPS),\n withPagination({\n initialPage: 0,\n })\n );\n\n this.sub$ = this.loadRequest$\n .pipe(\n filter((lr) => lr.endpoint !== '' || lr.force === true),\n distinctUntilChanged((prev, current) =>\n current.isEqualToAndNotForced(prev)\n ),\n switchMap((lr: LoadRequest) => this.doActualLoad(lr))\n )\n .subscribe();\n }\n\n /**\n * Stops listening for load requests and cleans up subscriptions.\n */\n stopLoader() {\n if (this.sub$) {\n this.sub$.unsubscribe();\n this.sub$ = undefined;\n }\n // Remove references to this component's pages from the cache. If this\n // is the only component using those cached pages, they will be cleared\n // from the cache.\n this.removeFromCache();\n }\n\n hasStarted(): boolean {\n return this.sub$ !== undefined;\n }\n\n /**\n * Returns a boolean indicating whether all entities at the remote have been\n * loaded. All entities are considered loaded when there are no more entities\n * to load from the remote (that is all pages have been loaded without\n * a search filter).\n * @returns\n */\n allEntitiesLoaded(): boolean {\n return this.store.query((state) => state.allEntitiesLoaded);\n }\n\n /**\n * Returns the total number of entities at the remote as reported by the\n * server (or load fn) during each load.\n * @returns\n */\n totalEntitiesAtRemote(): number {\n return this.store.query(getPaginationData()).total;\n }\n\n /**\n * Returns number of entities currently stored in the internal store.\n * @returns\n */\n totalEntitiesCount(): number {\n return this.store.query(getEntitiesCount());\n }\n\n /**\n * Returns true if there are more entities to load from the remote.\n * This is computed based on the total entities count and the number of\n * entities loaded so far. For this method to work correctly, an initial\n * load must have been performed to get the total count from the remote.\n * @returns\n */\n hasMore(): boolean {\n const paginationData = this.store.query(getPaginationData());\n return (\n Object.keys(paginationData.pages).length * paginationData.perPage <\n paginationData.total\n );\n // return this.store.query((state) => state.hasMore);\n }\n\n /**\n * Returns true if a load operation is in progress. The load async operation\n * method turns the loading state to true when a load operation starts and\n * turns it to false when the operation completes.\n * @returns\n */\n loading(): boolean {\n return this.store.query((state) => state.loading);\n }\n\n /**\n * Returns the endpoint URL if the loader was created with an endpoint.\n * If the loader was created with a loader function, an empty string is\n * returned.\n * @returns\n */\n endpoint(): string {\n return this.url() instanceof Function ? '' : (this.url() as string);\n }\n\n /**\n * Loads the specified page number of entities from the remote.\n * @param pageNumber\n */\n loadPage(pageNumber: number) {\n this.loadRequest$.next(\n new LoadRequest(this.url(), pageNumber, this.searchParamValue, false)\n );\n }\n\n /**\n * Returns the total number of pages available at the remote.\n * @returns\n */\n totalPages(): number {\n const paginationData = this.store.query(getPaginationData());\n return Math.ceil(paginationData.total / paginationData.perPage);\n }\n\n /**\n * Loads the next page of entities from the remote. If forceRefresh is true,\n * the internal store is reset before loading the next page. Use this for\n * infinite scroll scenarios where you want to load the pages sequentially.\n * @param forceRefresh\n */\n loadNextPage(forceRefresh = false) {\n const paginationData = this.store.query(getPaginationData());\n\n if (forceRefresh) {\n this.store.reset();\n } else if (paginationData.currentPage >= this.totalPages()) {\n return;\n }\n\n this.loadRequest$.next(\n new LoadRequest(\n this.url(),\n paginationData.currentPage,\n this.searchParamValue,\n false\n )\n );\n }\n\n setSearchParamValue(searchStr: string) {\n this.searchParamValue = searchStr;\n }\n\n setEntities(entities: TEntity[]) {\n this.store.update(upsertEntities(entities as any));\n }\n\n getEntities(): TEntity[] {\n return this.store.query(getAllEntities());\n }\n\n getEntity(id: TEntity[IdKey]): TEntity | undefined {\n return this.store.query(getEntity(id));\n }\n\n // Does the actual loading of entities from the remote or the loader\n // function. Once loaded, the entities are stored in the internal store and\n // pagination properties are updated.\n protected doActualLoad(lr: LoadRequest) {\n const loaderFn =\n typeof this.url() === 'function'\n ? (this.url() as SPEntityLoaderFn)\n : undefined;\n let obs: Observable<any>;\n let paramsObj: any = {};\n const pageSize = this._pageSize();\n if (loaderFn) {\n obs = (loaderFn as SPEntityLoaderFn)(\n lr.pageNumber,\n pageSize,\n lr.searchStr\n );\n paramsObj = {\n page: lr.pageNumber,\n pageSize,\n };\n if (lr.searchStr) {\n paramsObj[this.searchParamName()] = lr.searchStr || '';\n }\n } else {\n // Form the HttpParams which consists of pagination params and any\n // embedded params in the URL which doesn't conflict with the page\n // params.\n const urlParts = (this.url() as string).split('?');\n const pageParams = this._paginator().getRequestPageParams(\n urlParts[0],\n lr.pageNumber,\n pageSize\n );\n if (lr.searchStr) {\n pageParams[this.searchParamName()] = lr.searchStr || '';\n }\n let httpParams = new HttpParams({ fromObject: pageParams });\n if (this.httpParams()) {\n this.httpParams()!\n .keys()\n .forEach((key) => {\n const value = this.httpParams()!.getAll(key);\n (value || []).forEach((v) => {\n httpParams = httpParams.append(key, v);\n });\n });\n }\n if (urlParts.length > 1) {\n const embeddedParams = new HttpParams({ fromString: urlParts[1] });\n embeddedParams.keys().forEach((key) => {\n const value = embeddedParams.getAll(key);\n (value || []).forEach((v) => {\n if (!httpParams.has(key)) {\n httpParams = httpParams.append(key, v);\n }\n });\n });\n }\n const cacheKey = this.getCacheKey(urlParts[0], httpParams);\n if (this.existsInCache(cacheKey)) {\n obs = of(this.getFromCache(cacheKey));\n } else {\n obs = this.http\n .get<any>(urlParts[0], {\n context: this._httpReqContext(),\n params: httpParams,\n })\n .pipe(tap((resp) => this.addToCache(cacheKey, resp)));\n }\n\n // Convert HttpParams to JS object\n httpParams.keys().forEach((key) => {\n paramsObj[key] = httpParams.get(key);\n });\n }\n\n this.store.update(\n setProps((state) => ({\n ...state,\n loading: true,\n }))\n );\n return obs.pipe(\n // skipWhilePageExistsInCacheOrCache(cacheKey, resp),\n skipWhilePageExists(this.store, lr.pageNumber),\n tap((resp) => {\n let hasMore = false;\n\n let entities: TEntity[] = [];\n let total = 0;\n\n if (Array.isArray(resp)) {\n // If the response is an array, we assume it's the array of entities.\n // Obviously, in this case, there's no pagination and therefore\n // set the total number of entities to the length of the array.\n total = resp.length;\n entities = resp;\n } else {\n const result = this._paginator().parseRequestResponse(\n this.entityName(),\n this._pluralEntityName()!,\n this.endpoint(),\n paramsObj,\n resp\n );\n total = result.total;\n entities = result.entities as unknown as TEntity[];\n }\n\n this.store.update(\n upsertEntities(entities as any),\n setProps((state) => ({\n ...state,\n totalCount: total,\n })),\n updatePaginationData({\n total: total,\n perPage: this.pageSize(),\n lastPage: lr.pageNumber,\n currentPage: lr.pageNumber + 1,\n }),\n setPage(\n lr.pageNumber,\n entities.map((e) => (e as any)[this.idKey()])\n )\n );\n }),\n finalize(() => {\n this.store.update(\n setProps((state) => ({\n ...state,\n allEntitiesLoaded: !this.hasMore() && !this.searchParamValue,\n loading: false,\n }))\n );\n })\n );\n }\n\n private existsInCache(cacheKey: string): boolean {\n return SPPagedEntityLoader._entitiesCache.has(cacheKey);\n }\n\n private getCacheKey(url: string, params?: HttpParams): string {\n if (params) {\n return `${url}?${params.toString()}`;\n }\n return url;\n }\n\n private getFromCache(cacheKey: string): any {\n if (cacheKey && SPPagedEntityLoader._entitiesCache.has(cacheKey)) {\n return SPPagedEntityLoader._entitiesCache.get(cacheKey)?.resp;\n }\n return [];\n }\n\n addToCache(cacheKey: string, resp: any) {\n if (!SPPagedEntityLoader._entitiesCache.has(cacheKey)) {\n SPPagedEntityLoader._entitiesCache.set(cacheKey, {\n refCount: 0,\n resp,\n });\n }\n const cacheEntry = SPPagedEntityLoader._entitiesCache.get(cacheKey);\n cacheEntry!.refCount += 1;\n this.cacheKeys.add(cacheKey);\n }\n\n private removeFromCache() {\n for (const cacheKey of this.cacheKeys) {\n const cacheEntry = SPPagedEntityLoader._entitiesCache.get(cacheKey);\n if (cacheEntry) {\n cacheEntry!.refCount -= 1;\n if (cacheEntry.refCount <= 0) {\n SPPagedEntityLoader._entitiesCache.delete(cacheKey);\n }\n }\n }\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"smallpearl-ngx-helper-entities.mjs","sources":["../../../../projects/smallpearl/ngx-helper/entities/src/paged-loader.ts","../../../../projects/smallpearl/ngx-helper/entities/smallpearl-ngx-helper-entities.ts"],"sourcesContent":["import {\n HttpClient,\n HttpContext,\n HttpContextToken,\n HttpParams,\n} from '@angular/common/http';\nimport { computed, Directive, inject, input } from '@angular/core';\nimport { createStore, setProps, withProps } from '@ngneat/elf';\nimport { getAllEntities, getEntitiesCount, getEntity, upsertEntities, withEntities } from '@ngneat/elf-entities';\nimport { getPaginationData, setPage, skipWhilePageExists, updatePaginationData, withPagination } from '@ngneat/elf-pagination';\nimport { SP_MAT_ENTITY_LIST_CONFIG, SPMatEntityListPaginator, SPPageParams } from '@smallpearl/ngx-helper/mat-entity-list';\nimport { capitalize } from 'lodash';\nimport { plural } from 'pluralize';\nimport {\n distinctUntilChanged,\n filter,\n finalize,\n Observable,\n of,\n Subject,\n Subscription,\n switchMap,\n tap\n} from 'rxjs';\n\n/**\n * A type representing an entity loader function that takes page number,\n * page size, and an optional search value and returns an Observable of\n * the response. This is similar the http.get() method of HttpClient but\n * with pagination parameters. The return value is deliberately kept generic\n * (Observable<any>) to allow flexibility in the response type. This reponse\n * will be parsed by the provided paginator's parseRequestResponse() method.\n * So as long as the function return type and paginator are compatible,\n * any response type can be handled.\n *\n * Ideally the response should contain the total number of entities available\n * at the remote and the array of entities for the requested page.\n */\nexport type SPEntityLoaderFn = (\n page: number,\n pageSize: number,\n searchValue: string | undefined\n) => Observable<any>;\n\n/**\n * Represents a request to load entities from the remote. This is used to\n * compare two requests to determine if they are equal. This is useful to\n * prevent duplicate requests being sent to the remote.\n */\nclass LoadRequest {\n constructor(\n public endpoint: string | SPEntityLoaderFn,\n public pageNumber: number,\n public searchStr: string | undefined,\n public force = false\n ) {}\n\n // Returns true if two LoadRequest objects are equal and this object's\n // 'force' is not set to true.\n isEqualToAndNotForced(prev: LoadRequest): boolean {\n // console.log(\n // `isEqualToAndNotForced - ${this.endpoint}, ${this.params.toString()} ${\n // this.force\n // }, other: ${prev.endpoint}, ${prev.params.toString()}, ${prev.force}`\n // );\n return this.force\n ? false\n : (typeof this.endpoint === 'function' ||\n this.endpoint.localeCompare(prev.endpoint as string) === 0) &&\n this.pageNumber === prev.pageNumber &&\n this.searchStr === prev.searchStr;\n }\n}\n\ntype StateProps = {\n allEntitiesLoaded: boolean;\n loading: boolean;\n loaded: boolean\n};\n\nconst DEFAULT_STATE_PROPS: StateProps = {\n allEntitiesLoaded: false,\n loading: false,\n loaded: false\n}\n\n// Default paginator implementation. This can handle dynamic-rest and DRF\n// native pagination schemes. It also has a fallback to handle response conists\n// of an array of entities.\nclass DefaultPaginator implements SPMatEntityListPaginator {\n getRequestPageParams(\n endpoint: string,\n page: number,\n pageSize: number\n ): SPPageParams {\n return {\n page: page + 1,\n pageSize,\n };\n }\n\n parseRequestResponse<\n TEntity extends { [P in IdKey]: PropertyKey },\n IdKey extends string = 'id'\n >(\n entityName: string,\n entityNamePlural: string,\n endpoint: string,\n params: SPPageParams,\n resp: any\n ) {\n if (Array.isArray(resp)) {\n return {\n total: resp.length,\n entities: resp,\n };\n }\n\n if (typeof resp === 'object') {\n const keys = Object.keys(resp);\n // Handle dynamic-rest sideloaded response\n // Rudimentary sideloaded response support. This should work for most\n // of the sideloaded responses where the main entities are stored\n // under the plural entity name key and resp['meta'] object contains\n // the total count.\n if (\n keys.includes(entityNamePlural) &&\n Array.isArray(resp[entityNamePlural])\n ) {\n let total = resp[entityNamePlural].length;\n if (\n keys.includes('meta') &&\n typeof resp['meta'] === 'object' &&\n typeof resp['meta']['total'] === 'number'\n ) {\n total = resp['meta']['total'];\n }\n return {\n total,\n entities: resp[entityNamePlural],\n };\n }\n\n // Handle django-rest-framework style response\n if (keys.includes('results') && Array.isArray(resp['results'])) {\n let total = resp['results'].length;\n if (keys.includes('count') && typeof resp['count'] === 'number') {\n total = resp['count'];\n }\n return {\n total,\n entities: resp['results'],\n };\n }\n\n // Finally, look for \"items\" key\n if (keys.includes('items') && Array.isArray(resp['items'])) {\n return {\n total: resp['items'].length,\n entities: resp['items'],\n };\n }\n }\n\n return {\n total: 0,\n entities: [],\n };\n }\n}\n\n/**\n * An abstract class that you can use wherever you would like to load entities\n * from a remote endpoint in a paged manner. Entities can be loaded in one of\n * two ways:\n *\n * 1. By providing an entityLoaderFn that takes an endpoint and HttpParams\n * and returns a Observable of entities.\n * 2. Or by providing a URL and using the default loader that uses HttpClient\n * to load entities.\n * This class uses RxJS to manage the loading of entities and provides\n * signals to track the loading state, entity count, page index, page size,\n * and whether more entities are available to load.\n *\n * How to use this class:\n *\n * 1. Dervice your component from SPPagedEntityLoader.\n * 2. After your component is initialized, call the startLoader() method to\n * get the component going. This sets up the necessary subscriptions to\n * listen for load requests. Load requests are triggered by calling the\n * loadPage() or loadNextPage() methods.\n * 3. If your component supports infinite scrolling, call loadMoreEntities()\n * method to load the next page of entities when it detects a scroll event.\n * 4. If you component needs to load a specific page (via a pagination control),\n * call the loadPage(pageNumber) method to load the specified page.\n * 5. Entities are stored in an internal entities store which is an @ngneat/elf\n * store. You can subscribe to the store's query to get the list of entities.\n * 6. When your component is destroyed, call the stopLoader() method to clean up\n * internal subscriptions.\n *\n * The class is decorated with Angular's @Directive decorator so that we can\n * use signals for the input properties and dependency injection for HttpClient.\n * There are no abstract methods as such, but the class is meant to be extended\n * by your component to provide the necessary configuration via input properties.\n * This is why it is declared as abstract.\n */\n@Directive({\n selector: '**spPagedEntityLoader**',\n})\nexport abstract class SPPagedEntityLoader<\n TEntity extends { [P in IdKey]: PropertyKey },\n IdKey extends string = 'id'\n> {\n // We cache the entities that we fetch from remote here. Cache is indexed\n // by the endpoint. Each endpoint also keeps a refCount, which is incremented\n // for each instance of the component using the same endpoint. When this\n // refcount reaches 0, the endpoint is removed from the cache.\n //\n // This mechanism is to suppress multiple fetches from the remote from the\n // same endpoint as that can occur if a form has multiple instances of\n // this component with the same url.\n static _entitiesCache = new Map<string, { refCount: number; resp: any }>();\n // cache keys for this instance\n cacheKeys = new Set<string>();\n\n // Current search parameter value. This is used to load entities\n // matching the search string.\n searchParamValue: string | undefined;\n\n //** REQUIRED ATTRIBUTES **//\n /**\n * Entity name, that is used to form the \"New { item }\" menu item if\n * inlineNew=true. This is also used as the key of the object in GET response\n * if the reponse JSON is an object (sideloaded response), where the values\n * are stored indexed by the server model name. For eg:-\n *\n * {\n * 'customers': [\n * {...},\n * {...},\n * {...},\n * ]\n * }\n */\n entityName = input.required<string>();\n url = input.required<string | SPEntityLoaderFn>();\n\n //** OPTIONAL ATTRIBUTES **//\n // Number of entities to be loaded per page from the server. This will be\n // passed to PagedEntityLoader to load entities in pages. Defaults to 50.\n // Adjust this accordingly based on the average size of your entities to\n // optimize server round-trips and memory usage.\n pageSize = input<number>(50);\n\n // Paginator for the remote entity list. This is used to determine the\n // pagination parameters for the API request. If not specified, the global\n // paginator specified in SPMatEntityListConfig will be used. If that too is\n // not specified, a default paginator will be used. Default paginator can\n // handle DRF native PageNumberPagination and dynamic-rest style pagination.\n paginator = input<SPMatEntityListPaginator>();\n\n // Search parameter name to be used in the HTTP request.\n // Defaults to 'search'. That is when a search string is specified and\n // the entire entity list has not been fetched, a fresh HTTP request is made\n // to the remote server with `?<searchParamName>=<search string>` parameter.\n searchParamName = input<string>('search');\n\n // Entity idKey, if idKey is different from the default 'id'.\n idKey = input<string>('id');\n\n // Plural entity name, used when grouping options. If not specified, it is\n // derived by pluralizing the entityName.\n pluralEntityName = input<string | undefined>(undefined); // defaults to pluralized entityName\n\n httpReqContext = input<\n [[HttpContextToken<any>, any]] | [HttpContextToken<any>, any] | undefined\n >(undefined); // defaults to empty context\n\n // Parameters to be added to the HTTP request to retrieve data from\n // remote. This won't be used if `loadFromRemoteFn` is specified.\n httpParams = input<HttpParams | undefined>(undefined); // defaults to empty params\n\n // Mechanism to default pageSize to last entities length.\n protected loadRequest$ = new Subject<LoadRequest>();\n protected sub$: Subscription | undefined;\n protected _pageSize = computed<number>(() =>\n this.pageSize() ? this.pageSize() : 50\n );\n\n protected _pluralEntityName = computed<string>(() => {\n const pluralEntityName = this.pluralEntityName();\n return pluralEntityName ? pluralEntityName : plural(this.entityName());\n });\n\n protected _capitalizedEntityName = computed<string>(() =>\n capitalize(this.entityName())\n );\n\n protected _httpReqContext = computed(() => {\n let reqContext = this.httpReqContext();\n const context = new HttpContext();\n if (reqContext && Array.isArray(reqContext)) {\n if (reqContext.length == 2 && !Array.isArray(reqContext[0])) {\n // one dimensional array of a key, value pair.\n context.set(reqContext[0], reqContext[1]);\n } else {\n reqContext.forEach(([k, v]) => context.set(k, v));\n }\n }\n return context;\n });\n\n entityListConfig = inject(SP_MAT_ENTITY_LIST_CONFIG, {\n optional: true,\n });\n protected _paginator = computed<SPMatEntityListPaginator>(() => {\n const paginator = this.paginator();\n const entityListConfigPaginator = this.entityListConfig\n ? (this.entityListConfig.paginator as SPMatEntityListPaginator)\n : undefined;\n return paginator\n ? paginator\n : entityListConfigPaginator\n ? entityListConfigPaginator\n : new DefaultPaginator();\n });\n\n // We create it here so that store member variable will have the correct\n // type. Unfortunately elf doesn't have a simple generic type that we can\n // use to declare the type of the store and then initialize it later.\n // We will recreate it in the constructor to have the correct idKey.\n protected store = createStore(\n { name: Math.random().toString(36).slice(2) },\n withEntities<TEntity, IdKey>({ idKey: 'id' as IdKey }),\n withProps<StateProps>(DEFAULT_STATE_PROPS),\n withPagination({\n initialPage: 0,\n })\n );\n\n protected http = inject(HttpClient);\n\n constructor() {}\n\n /**\n * Starts listening for load requests and processes them. Call this from your\n * component's ngOnInit() or ngAfterViewInit() method.\n */\n startLoader() {\n // Recreate store with the correct idKey. We have to do this after\n // the idKey is available from the constructor argument.\n const entities = this.store.query(getAllEntities());\n this.store = createStore(\n { name: Math.random().toString(36).slice(2) },\n withEntities<TEntity, IdKey>({ initialValue: entities, idKey: this.idKey() as IdKey }),\n withProps<StateProps>(DEFAULT_STATE_PROPS),\n withPagination({\n initialPage: 0,\n })\n );\n\n this.sub$ = this.loadRequest$\n .pipe(\n filter((lr) => lr.endpoint !== '' || lr.force === true),\n distinctUntilChanged((prev, current) =>\n current.isEqualToAndNotForced(prev)\n ),\n switchMap((lr: LoadRequest) => this.doActualLoad(lr))\n )\n .subscribe();\n }\n\n /**\n * Stops listening for load requests and cleans up subscriptions.\n */\n stopLoader() {\n if (this.sub$) {\n this.sub$.unsubscribe();\n this.sub$ = undefined;\n }\n // Remove references to this component's pages from the cache. If this\n // is the only component using those cached pages, they will be cleared\n // from the cache.\n this.removeFromCache();\n }\n\n hasStarted(): boolean {\n return this.sub$ !== undefined;\n }\n\n /**\n * Returns a boolean indicating whether all entities at the remote have been\n * loaded. All entities are considered loaded when there are no more entities\n * to load from the remote (that is all pages have been loaded without\n * a search filter).\n * @returns\n */\n allEntitiesLoaded(): boolean {\n return this.store.query((state) => state.allEntitiesLoaded);\n }\n\n /**\n * Returns the total number of entities at the remote as reported by the\n * server (or load fn) during each load.\n * @returns\n */\n totalEntitiesAtRemote(): number {\n return this.store.query(getPaginationData()).total;\n }\n\n /**\n * Returns number of entities currently stored in the internal store.\n * @returns\n */\n totalEntitiesCount(): number {\n return this.store.query(getEntitiesCount());\n }\n\n /**\n * Returns true if there are more entities to load from the remote.\n * This is computed based on the total entities count and the number of\n * entities loaded so far. For this method to work correctly, an initial\n * load must have been performed to get the total count from the remote.\n * @returns\n */\n hasMore(): boolean {\n const paginationData = this.store.query(getPaginationData());\n return (\n Object.keys(paginationData.pages).length * paginationData.perPage <\n paginationData.total\n );\n // return this.store.query((state) => state.hasMore);\n }\n\n /**\n * Returns true if a load operation is in progress. The load async operation\n * method turns the loading state to true when a load operation starts and\n * turns it to false when the operation completes.\n * @returns\n */\n loading(): boolean {\n return this.store.query((state) => state.loading);\n }\n\n /**\n * Boolean indicates whether the loader has completed at least one load\n * operation.\n */\n loaded(): boolean {\n return this.store.query((state) => state.loaded);\n }\n\n /**\n * Returns the endpoint URL if the loader was created with an endpoint.\n * If the loader was created with a loader function, an empty string is\n * returned.\n * @returns\n */\n endpoint(): string {\n return this.url() instanceof Function ? '' : (this.url() as string);\n }\n\n /**\n * Loads the specified page number of entities from the remote.\n * @param pageNumber\n */\n loadPage(pageNumber: number) {\n this.loadRequest$.next(\n new LoadRequest(this.url(), pageNumber, this.searchParamValue, false)\n );\n }\n\n /**\n * Returns the total number of pages available at the remote.\n * @returns\n */\n totalPages(): number {\n const paginationData = this.store.query(getPaginationData());\n return Math.ceil(paginationData.total / paginationData.perPage);\n }\n\n /**\n * Loads the next page of entities from the remote. If forceRefresh is true,\n * the internal store is reset before loading the next page. Use this for\n * infinite scroll scenarios where you want to load the pages sequentially.\n * @param forceRefresh\n */\n loadNextPage(forceRefresh = false) {\n const paginationData = this.store.query(getPaginationData());\n\n if (forceRefresh) {\n this.store.reset();\n } else if (paginationData.currentPage >= this.totalPages()) {\n return;\n }\n\n this.loadRequest$.next(\n new LoadRequest(\n this.url(),\n paginationData.currentPage,\n this.searchParamValue,\n false\n )\n );\n }\n\n setSearchParamValue(searchStr: string) {\n this.searchParamValue = searchStr;\n }\n\n setEntities(entities: TEntity[]) {\n this.store.update(upsertEntities(entities as any));\n }\n\n getEntities(): TEntity[] {\n return this.store.query(getAllEntities());\n }\n\n getEntity(id: TEntity[IdKey]): TEntity | undefined {\n return this.store.query(getEntity(id));\n }\n\n // Does the actual loading of entities from the remote or the loader\n // function. Once loaded, the entities are stored in the internal store and\n // pagination properties are updated.\n protected doActualLoad(lr: LoadRequest) {\n const loaderFn =\n typeof this.url() === 'function'\n ? (this.url() as SPEntityLoaderFn)\n : undefined;\n let obs: Observable<any>;\n let paramsObj: any = {};\n const pageSize = this._pageSize();\n if (loaderFn) {\n obs = (loaderFn as SPEntityLoaderFn)(\n lr.pageNumber,\n pageSize,\n lr.searchStr\n );\n paramsObj = {\n page: lr.pageNumber,\n pageSize,\n };\n if (lr.searchStr) {\n paramsObj[this.searchParamName()] = lr.searchStr || '';\n }\n } else {\n // Form the HttpParams which consists of pagination params and any\n // embedded params in the URL which doesn't conflict with the page\n // params.\n const urlParts = (this.url() as string).split('?');\n const pageParams = this._paginator().getRequestPageParams(\n urlParts[0],\n lr.pageNumber,\n pageSize\n );\n if (lr.searchStr) {\n pageParams[this.searchParamName()] = lr.searchStr || '';\n }\n let httpParams = new HttpParams({ fromObject: pageParams });\n if (this.httpParams()) {\n this.httpParams()!\n .keys()\n .forEach((key) => {\n const value = this.httpParams()!.getAll(key);\n (value || []).forEach((v) => {\n httpParams = httpParams.append(key, v);\n });\n });\n }\n if (urlParts.length > 1) {\n const embeddedParams = new HttpParams({ fromString: urlParts[1] });\n embeddedParams.keys().forEach((key) => {\n const value = embeddedParams.getAll(key);\n (value || []).forEach((v) => {\n if (!httpParams.has(key)) {\n httpParams = httpParams.append(key, v);\n }\n });\n });\n }\n const cacheKey = this.getCacheKey(urlParts[0], httpParams);\n if (this.existsInCache(cacheKey)) {\n obs = of(this.getFromCache(cacheKey));\n } else {\n obs = this.http\n .get<any>(urlParts[0], {\n context: this._httpReqContext(),\n params: httpParams,\n })\n .pipe(tap((resp) => this.addToCache(cacheKey, resp)));\n }\n\n // Convert HttpParams to JS object\n httpParams.keys().forEach((key) => {\n paramsObj[key] = httpParams.get(key);\n });\n }\n\n this.store.update(\n setProps((state) => ({\n ...state,\n loading: true,\n }))\n );\n return obs.pipe(\n // skipWhilePageExistsInCacheOrCache(cacheKey, resp),\n skipWhilePageExists(this.store, lr.pageNumber),\n tap((resp) => {\n let hasMore = false;\n\n let entities: TEntity[] = [];\n let total = 0;\n\n if (Array.isArray(resp)) {\n // If the response is an array, we assume it's the array of entities.\n // Obviously, in this case, there's no pagination and therefore\n // set the total number of entities to the length of the array.\n total = resp.length;\n entities = resp;\n } else {\n const result = this._paginator().parseRequestResponse(\n this.entityName(),\n this._pluralEntityName()!,\n this.endpoint(),\n paramsObj,\n resp\n );\n total = result.total;\n entities = result.entities as unknown as TEntity[];\n }\n\n this.store.update(\n upsertEntities(entities as any),\n setProps((state) => ({\n ...state,\n totalCount: total,\n })),\n updatePaginationData({\n total: total,\n perPage: this.pageSize(),\n lastPage: lr.pageNumber,\n currentPage: lr.pageNumber + 1,\n }),\n setPage(\n lr.pageNumber,\n entities.map((e) => (e as any)[this.idKey()])\n )\n );\n }),\n finalize(() => {\n this.store.update(\n setProps((state) => ({\n ...state,\n allEntitiesLoaded: !this.hasMore() && !this.searchParamValue,\n loading: false,\n loaded: true\n }))\n );\n })\n );\n }\n\n private existsInCache(cacheKey: string): boolean {\n return SPPagedEntityLoader._entitiesCache.has(cacheKey);\n }\n\n private getCacheKey(url: string, params?: HttpParams): string {\n if (params) {\n return `${url}?${params.toString()}`;\n }\n return url;\n }\n\n private getFromCache(cacheKey: string): any {\n if (cacheKey && SPPagedEntityLoader._entitiesCache.has(cacheKey)) {\n return SPPagedEntityLoader._entitiesCache.get(cacheKey)?.resp;\n }\n return [];\n }\n\n addToCache(cacheKey: string, resp: any) {\n if (!SPPagedEntityLoader._entitiesCache.has(cacheKey)) {\n SPPagedEntityLoader._entitiesCache.set(cacheKey, {\n refCount: 0,\n resp,\n });\n }\n const cacheEntry = SPPagedEntityLoader._entitiesCache.get(cacheKey);\n cacheEntry!.refCount += 1;\n this.cacheKeys.add(cacheKey);\n }\n\n private removeFromCache() {\n for (const cacheKey of this.cacheKeys) {\n const cacheEntry = SPPagedEntityLoader._entitiesCache.get(cacheKey);\n if (cacheEntry) {\n cacheEntry!.refCount -= 1;\n if (cacheEntry.refCount <= 0) {\n SPPagedEntityLoader._entitiesCache.delete(cacheKey);\n }\n }\n }\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -778,8 +778,7 @@ class SPMatSelectEntityComponent extends SPPagedEntityLoader {
778
778
  The logic behind this behavior being that user searches for a matching
779
779
  item and when not finding one, would like to add a new one.
780
780
  -->
781
- @if (inlineNew() && (filterStr.length > 0 || totalEntitiesAtRemote() ===
782
- 0)) {
781
+ @if (inlineNew() && loaded() && (filterStr.length > 0 || totalEntitiesAtRemote() === 0)) {
783
782
  <mat-option
784
783
  class="add-item-option"
785
784
  value="0"
@@ -883,8 +882,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.6", ngImpor
883
882
  The logic behind this behavior being that user searches for a matching
884
883
  item and when not finding one, would like to add a new one.
885
884
  -->
886
- @if (inlineNew() && (filterStr.length > 0 || totalEntitiesAtRemote() ===
887
- 0)) {
885
+ @if (inlineNew() && loaded() && (filterStr.length > 0 || totalEntitiesAtRemote() === 0)) {
888
886
  <mat-option
889
887
  class="add-item-option"
890
888
  value="0"
@@ -1 +1 @@
1
- {"version":3,"file":"smallpearl-ngx-helper-mat-select-entity.mjs","sources":["../../../../projects/smallpearl/ngx-helper/mat-select-entity/src/mat-select-entity.component.ts","../../../../projects/smallpearl/ngx-helper/mat-select-entity/smallpearl-ngx-helper-mat-select-entity.ts"],"sourcesContent":["import { BooleanInput, coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { CommonModule, NgTemplateOutlet } from '@angular/common';\nimport {\n HttpContext,\n HttpContextToken\n} from '@angular/common/http';\nimport {\n AfterViewInit,\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n computed,\n ElementRef,\n EventEmitter,\n HostBinding,\n inject,\n input,\n Input,\n OnDestroy,\n OnInit,\n Output,\n TemplateRef,\n viewChild,\n} from '@angular/core';\nimport {\n ControlValueAccessor,\n FormsModule,\n NgControl,\n ReactiveFormsModule,\n Validators,\n} from '@angular/forms';\nimport { MatButtonModule } from '@angular/material/button';\nimport {\n MAT_FORM_FIELD,\n MatFormFieldControl,\n} from '@angular/material/form-field';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatProgressSpinnerModule } from '@angular/material/progress-spinner';\nimport {\n MatSelect,\n MatSelectChange,\n MatSelectModule,\n} from '@angular/material/select';\nimport {\n provideTranslocoScope,\n TranslocoModule,\n TranslocoService,\n} from '@jsverse/transloco';\nimport { getEntity, hasEntity, selectAllEntities, upsertEntities } from '@ngneat/elf-entities';\nimport {\n SPPagedEntityLoader\n} from '@smallpearl/ngx-helper/entities';\nimport {\n SPMatEntityListPaginator,\n SPPageParams,\n} from '@smallpearl/ngx-helper/mat-entity-list';\nimport { MatSelectInfiniteScrollDirective } from '@smallpearl/ngx-helper/mat-select-infinite-scroll';\nimport { NgxMatSelectSearchModule } from 'ngx-mat-select-search';\nimport {\n combineLatest,\n debounceTime,\n distinctUntilChanged,\n Observable,\n startWith,\n Subject,\n takeUntil,\n tap\n} from 'rxjs';\n\n\nexport interface SPMatSelectEntityHttpContext {\n entityName: string;\n entityNamePlural: string;\n endpoint: string;\n}\n\nexport const SP_MAT_SELECT_ENTITY_HTTP_CONTEXT =\n new HttpContextToken<SPMatSelectEntityHttpContext>(() => ({\n entityName: '',\n entityNamePlural: '',\n endpoint: '',\n }));\n\n// Internal type to represent a group of entities. Used when grouping is enabled.\ntype EntityGroup<TEntity> = {\n label: string;\n entities: TEntity[];\n};\n\nexport type SPMatSelectEntityResponseParser = <\n TEntity extends { [P in IdKey]: PropertyKey },\n IdKey extends string = 'id'\n>(\n response: any\n) => Array<TEntity>;\n\n// Default paginator implementation. This can handle dynamic-rest and DRF\n// native pagination schemes. It also has a fallback to handle response conists\n// of an array of entities.\nclass DefaultPaginator implements SPMatEntityListPaginator {\n getRequestPageParams(\n endpoint: string,\n page: number,\n pageSize: number\n ): SPPageParams {\n return {\n page: page + 1,\n pageSize,\n };\n }\n\n parseRequestResponse<\n TEntity extends { [P in IdKey]: PropertyKey },\n IdKey extends string = 'id'\n >(\n entityName: string,\n entityNamePlural: string,\n endpoint: string,\n params: SPPageParams,\n resp: any\n ) {\n if (Array.isArray(resp)) {\n return {\n total: resp.length,\n entities: resp,\n };\n }\n\n if (typeof resp === 'object') {\n const keys = Object.keys(resp);\n // Handle dynamic-rest sideloaded response\n // Rudimentary sideloaded response support. This should work for most\n // of the sideloaded responses where the main entities are stored\n // under the plural entity name key and resp['meta'] object contains\n // the total count.\n if (\n keys.includes(entityNamePlural) &&\n Array.isArray(resp[entityNamePlural])\n ) {\n let total = resp[entityNamePlural].length;\n if (\n keys.includes('meta') &&\n typeof resp['meta'] === 'object' &&\n typeof resp['meta']['total'] === 'number'\n ) {\n total = resp['meta']['total'];\n }\n return {\n total,\n entities: resp[entityNamePlural],\n };\n }\n\n // Handle django-rest-framework style response\n if (keys.includes('results') && Array.isArray(resp['results'])) {\n let total = resp['results'].length;\n if (keys.includes('count') && typeof resp['count'] === 'number') {\n total = resp['count'];\n }\n return {\n total,\n entities: resp['results'],\n };\n }\n\n // Finally, look for \"items\" key\n if (keys.includes('items') && Array.isArray(resp['items'])) {\n return {\n total: resp['items'].length,\n entities: resp['items'],\n };\n }\n }\n\n return {\n total: 0,\n entities: [],\n };\n }\n}\n\n/**\n * This is a generic component to display a <mat-select> for a FK field\n * where the select's options are dynamically loaded from the server using\n * the given url (or URL). The objects thus retrieved should have a\n * unique 'id' field that will be used as the value of each `option` element.\n * Therefore upon selection of an `option` element, the `select` value will\n * be set to the object's `id` property. By default 'id' is used as its id,\n * but this can be customized by specifying the `idKey' property value.\n */\n@Component({\n selector: 'sp-mat-select-entity',\n template: `\n <div\n *transloco=\"let t; scope: 'sp-mat-select-entity'\"\n (focusin)=\"onFocusIn($event)\"\n (focusout)=\"onFocusOut($event)\"\n role=\"group\"\n [attr.aria-labelledby]=\"_formField?.getLabelId()\"\n >\n <mat-select\n [placeholder]=\"placeholder\"\n (opened)=\"onSelectOpened($event)\"\n (selectionChange)=\"onSelectionChange($event)\"\n [multiple]=\"multiple()\"\n [(ngModel)]=\"selectValue\"\n msInfiniteScroll\n (infiniteScroll)=\"onInfiniteScroll()\"\n >\n <mat-select-trigger>\n {{ selectTriggerValue }}\n @if (selectTriggerValueAsArray.length > 1) {\n <span class=\"addl-selection-count\">\n (+{{ selectTriggerValueAsArray.length - 1 }})\n </span>\n }\n </mat-select-trigger>\n\n <mat-option [disabled]=\"totalEntitiesCount() === 0\">\n <ngx-mat-select-search\n class=\"flex-grow-1\"\n [(ngModel)]=\"filterStr\"\n (ngModelChange)=\"this.filter$.next($event)\"\n [placeholderLabel]=\"\n searchText() ? searchText() : t('spMatSelectEntity.search')\n \"\n [noEntriesFoundLabel]=\"\n notFoundText() ? notFoundText() : t('spMatSelectEntity.notFound')\n \"\n [searching]=\"searching\"\n >\n </ngx-mat-select-search>\n </mat-option>\n\n <ng-template #defaultOptionLabelTemplate let-entity>\n {{ _entityLabelFn()(entity) }}\n </ng-template>\n @if (!_group()) { @if (filteredValues | async; as entities) { @for\n (entity of entities; track entityId(entity)) {\n <mat-option class=\"sel-entity-option\" [value]=\"entityId(entity)\">\n <ng-container\n *ngTemplateOutlet=\"\n optionLabelTemplate() || defaultOptionLabelTemplate;\n context: { $implicit: entity }\n \"\n ></ng-container>\n </mat-option>\n } } } @else { @if (filteredGroupedValues | async; as groups) { @for\n (group of groups; track group.label) {\n <mat-optgroup [label]=\"group.label\">\n @for (entity of group.entities; track entityId(entity)) {\n <mat-option class=\"sel-entity-option\" [value]=\"entityId(entity)\">\n <ng-container\n *ngTemplateOutlet=\"\n optionLabelTemplate() || defaultOptionLabelTemplate;\n context: { $implicit: entity }\n \"\n ></ng-container>\n </mat-option>\n }\n </mat-optgroup>\n } } }\n\n <!--\n Create New option is displayed only if there is a filter string.\n The logic behind this behavior being that user searches for a matching\n item and when not finding one, would like to add a new one.\n -->\n @if (inlineNew() && (filterStr.length > 0 || totalEntitiesAtRemote() ===\n 0)) {\n <mat-option\n class=\"add-item-option\"\n value=\"0\"\n (click)=\"$event.stopPropagation()\"\n >⊕\n {{\n this.createNewText()\n ? this.createNewText()\n : t('spMatSelectEntity.createNew', {\n item: this._capitalizedEntityName()\n })\n }}\n </mat-option>\n } @if (loading()) {\n <div class=\"loading-wrapper\">\n <mat-progress-spinner\n diameter=\"24\"\n mode=\"indeterminate\"\n ></mat-progress-spinner>\n </div>\n }\n </mat-select>\n </div>\n `,\n styles: [\n `\n .add-item-option {\n padding-top: 2px;\n border-top: 1px solid var(--mat-sys-outline);\n }\n .addl-selection-count {\n opacity: 0.75;\n font-size: 0.8em;\n }\n .loading-wrapper {\n display: flex;\n justify-content: center;\n padding: 8px 0;\n }\n `,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [\n CommonModule,\n NgTemplateOutlet,\n FormsModule,\n ReactiveFormsModule,\n MatSelectModule,\n MatButtonModule,\n MatIconModule,\n MatProgressSpinnerModule,\n TranslocoModule,\n NgxMatSelectSearchModule,\n MatSelectInfiniteScrollDirective,\n ],\n providers: [\n provideTranslocoScope('sp-mat-select-entity'),\n { provide: MatFormFieldControl, useExisting: SPMatSelectEntityComponent },\n ],\n})\nexport class SPMatSelectEntityComponent<\n TEntity extends { [P in IdKey]: PropertyKey },\n IdKey extends string = 'id'\n >\n extends SPPagedEntityLoader<TEntity, IdKey>\n implements\n OnInit,\n OnDestroy,\n AfterViewInit,\n ControlValueAccessor,\n MatFormFieldControl<string | number | string[] | number[]>\n{\n // We cache the entities that we fetch from remote here. Cache is indexed\n // by the endpoint. Each endpoint also keeps a refCount, which is incremented\n // for each instance of the component using the same endpoint. When this\n // refcount reaches 0, the endpoint is removed from the cache.\n //\n // This mechanism is to suppress multiple fetches from the remote from the\n // same endpoint as that can occur if a form has multiple instances of\n // this component with the same url.\n // static _entitiesCache = new Map<\n // string,\n // { refCount: number; entities: Array<any> }\n // >();\n\n //**** OPTIONAL ATTRIBUTES ****//\n\n // Entity label function - function that takes an entity object and returns\n // a string label for it. If not specified, a default label function is used\n // that returns the value of 'name' or 'label' or 'title' property. If\n // none of these properties are present, the entity's id is returned as\n // string.\n labelFn = input<(entity: TEntity) => string>();\n\n // Entity filter function - return a boolean if the entity is to be included\n // in the filtered entities list.\n filterFn = input<(entity: TEntity, search: string) => boolean>();\n\n // Set to true to show \"Add { item }\" option in the select dropdown.\n // Selecting this option, will emit `createNewItemSelected` event.\n inlineNew = input<boolean>(false);\n\n // Set to true to allow multiple option selection. The returned value\n // would be an array of entity ids.\n multiple = input<boolean>(false);\n\n /**\n * The entity key name that is used to classify entities into groups.\n * Entities with the same key value will be grouped together. If this is\n * specified, grouping will be enabled.\n * @see groupByFn\n */\n groupOptionsKey = input<string>();\n\n /**\n * A function that takes a TEntity and returns the group id (string)\n * that the entity belongs to. If this is specified, grouping of entities\n * in the select will be enabled. This takes precedence over\n * `groupOptionsKey`.\n * @see groupOptionsKey\n */\n groupByFn = input<(entity: TEntity) => string>();\n\n @Output() selectionChange = new EventEmitter<TEntity | TEntity[]>();\n @Output() createNewItemSelected = new EventEmitter<void>();\n\n // i18n localization support toallow per component customization of\n // some strings used.\n readonly searchText = input<string>();\n readonly notFoundText = input<string>();\n readonly createNewText = input<string>();\n\n controlType = 'sp-mat-select-entity';\n\n /**\n * Template for the option label. If not provided, the default label\n * function will be used. Option label is what is placed inside the\n * <mat-option> tag. The template gets an implicit 'entity' variable\n * in the context, value for which is the entity object.\n *\n * For example:\n * ```\n * <sp-mat-select-entity\n * [url]=\"'/api/v1/customers/'\"\n * [labelFn]=\"entity => entity.name\"\n * [optionLabelTemplate]=\"optionLabelTemplate\"\n * ></sp-mat-select-entity>\n * <ng-template #optionLabelTemplate let-entity>\n * {{ entity.name }} - {{ entity.description }}\n * </ng-template>\n * ```\n */\n optionLabelTemplate = input<TemplateRef<any>>();\n\n // a computed version of labelFn that provides a default implementation\n protected _entityLabelFn = computed<(entity: TEntity) => string>(() => {\n const fn = this.labelFn();\n if (fn) {\n return fn;\n }\n return (entity: TEntity) => {\n return (\n (entity as any)['name'] ||\n (entity as any)['label'] ||\n (entity as any)['title'] ||\n String((entity as any)[this.idKey()])\n );\n };\n });\n\n // Whether to group options. Grouping is enabled when either groupOptionsKey\n // or groupByFn is specified.\n protected _group = computed<boolean>(() => {\n return !!this.groupOptionsKey() || !!this.groupByFn();\n });\n\n protected _groupEntitiesKey = computed<string>(() => {\n const groupOptionsKey = this.groupOptionsKey();\n return groupOptionsKey\n ? groupOptionsKey\n : this.entityName()\n ? this._pluralEntityName()\n : 'items';\n });\n\n // For the global paginator. We'll abstract this into an independent\n // configuration that can be shared across both mat-entity-list and\n // mat-select-entity later.\n // entityListConfig = getEntityListConfig();\n\n // protected _paginator = computed<SPMatEntityListPaginator>(() => {\n // const paginator = this.paginator();\n // const entityListConfigPaginator = this.entityListConfig\n // ?.paginator as SPMatEntityListPaginator;\n // return paginator\n // ? paginator\n // : entityListConfigPaginator ?? new DefaultPaginator();\n // });\n\n stateChanges = new Subject<void>();\n focused = false;\n touched = false;\n\n selectValue!: string | number | string[] | number[];\n // To store initial value when writeValue() is called before entities are\n // loaded, either by entities() input or via paged loader. This is especially\n // necessary when the elf store uses an idKey other than 'id'.\n _initialValue: string | number | string[] | number[] | undefined = undefined;\n\n // For storing last select value, which we use to restore the select's value\n // to when New Item is selected. This ensures that when New Item is selected,\n // the select's value remains the same. If the newly created item is to be\n // set as the select's value, the corresponding TEntity has to be added\n // to _entities (via addEntity()) and then selected by setting the\n // corresponding formControl's value to the entity's id.\n lastSelectValue!: string | number | string[] | number[];\n searching = false;\n filterStr: string = '';\n\n filter$ = new Subject<string>();\n\n // ControlValueAccessor callbacks\n onChanged = (_: any) => {};\n onTouched = () => {};\n\n // @ViewChild(MatSelect) matSelect!: MatSelect;\n matSelect = viewChild(MatSelect);\n\n filteredValues = new Subject<TEntity[]>();\n filteredGroupedValues = new Subject<EntityGroup<TEntity>[]>();\n\n destroy = new Subject<void>();\n\n static nextId = 0;\n @HostBinding() id = `sp-select-entity-${SPMatSelectEntityComponent.nextId++}`;\n private _placeholder!: string;\n //protected http = inject(HttpClient);\n protected cdr = inject(ChangeDetectorRef);\n protected _elementRef = inject(ElementRef<HTMLElement>);\n protected _formField = inject(MAT_FORM_FIELD, { optional: true });\n public ngControl = inject(NgControl, { optional: true });\n transloco = inject(TranslocoService);\n\n // pagedEntityLoader!: SPPagedEntityLoader<TEntity, IdKey>;\n\n constructor() {\n super();\n if (this.ngControl != null) {\n this.ngControl.valueAccessor = this;\n }\n }\n\n /**\n * Conditions for loading entities:\n *\n * 1. When the select is opened, if entities have not already been loaded.\n * 2. When the search string changes.\n * 3. When the scroll reaches the bottom and more entities are available\n * to be loaded.\n *\n * We need to create an 'observer-loop' that can handle the above.\n */\n\n ngOnInit() {\n this.startLoader();\n // A rudimentary mechanism to detect which of the two observables\n // emitted the latest value. We reset this array to 'false' after\n // processing every combined emission.\n const emittedObservable = [false, false];\n const store$ = this.store.pipe(selectAllEntities());\n const filter$ = this.filter$.pipe(\n startWith(''),\n distinctUntilChanged(),\n debounceTime(400)\n );\n\n const emittedStatusObservable = (obs: Observable<any>, index: number) =>\n obs.pipe(tap(() => (emittedObservable[index] = true)));\n\n // We need to determine if the emission is owing to a change in\n // filterStr or a change in the entities in pagedEntityLoader.store$.\n //\n // 1. If entities in pagedEntityLoader.store$ have changed, we just need\n // to filter the entities in local store using the current filterStr.\n // 2. If filterStr has changed, there are two cases to handle:-\n // a. If all entities have been loaded, we don't need to reload\n // entities. Instead we just have to filter the entities in\n // local store using the filterStr.\n // b. If all entities have not been loaded, we trigger a server\n // load with the new filterStr as the search param.\n //\n // The following logic implements the above.\n combineLatest([\n emittedStatusObservable(store$, 0),\n emittedStatusObservable(filter$, 1),\n ])\n .pipe(\n takeUntil(this.destroy),\n tap(([entities, filterStr]) => {\n if (emittedObservable.every((eo) => eo)) {\n // initial emission. This can be combined with the case immediately\n // below it. But we keep it separate for clarity.\n emittedObservable[0] = emittedObservable[1] = false;\n this.filterEntities(entities, filterStr);\n } else if (emittedObservable[0]) {\n emittedObservable[0] = false;\n this.filterEntities(entities, filterStr);\n } else {\n emittedObservable[1] = false;\n if (this.allEntitiesLoaded()) {\n this.filterEntities(entities, filterStr);\n } else {\n this.setSearchParamValue(filterStr);\n // This will cause an emission from store$ observable as the\n // 'forceRefresh=true' arg causes the store to be reset.\n this.loadNextPage(true);\n }\n }\n })\n )\n .subscribe();\n\n if (this._initialValue !== undefined) {\n this.writeValue(this._initialValue);\n this._initialValue = undefined;\n }\n }\n\n ngOnDestroy(): void {\n this.destroy.next();\n this.destroy.complete();\n this.stopLoader();\n // this.removeFromCache();\n this.stateChanges.complete();\n }\n\n ngAfterViewInit(): void {\n // I'm not sure this is how this logic is right, but this seems to work.\n // if (this.ngControl && this.ngControl.control?.validator) {\n // const validator = this.ngControl.control.validator;\n // const res = validator(this.ngControl.control);\n // if (res && res['required']) {\n // this.required = true;\n // }\n // }\n // load first page\n // this.loadMoreEntities();\n }\n\n addEntity(entity: TEntity) {\n this.store.update(upsertEntities(entity));\n this.cdr.detectChanges();\n }\n\n get selectTriggerValue() {\n if (this.selectValue) {\n const firstSelected = Array.isArray(this.selectValue)\n ? this.selectValue[0]\n : this.selectValue;\n const selectedEntity = this.getEntity(firstSelected as TEntity[IdKey]);\n return selectedEntity ? this._entityLabelFn()(selectedEntity) : '';\n }\n return '';\n }\n\n get selectTriggerValueAsArray() {\n return Array.isArray(this.selectValue)\n ? (this.selectValue as Array<string | number>)\n : [];\n }\n\n entityId(entity: TEntity) {\n return (entity as any)[this.idKey()];\n }\n\n writeValue(entityId: string | number | string[] | number[]): void {\n // If the component has not yet started (calling startLoader()), we store\n // the initial value in _initialValue and return. The actual setting of\n // the value will happen after startLoader() is called from ngOnInit().\n if (!this.hasStarted()) {\n this._initialValue = entityId;\n return;\n }\n\n const store = this.store;\n const entities = this.getEntities();\n if (Array.isArray(entityId)) {\n if (this.multiple()) {\n const selectedValues: any[] = [];\n entityId.forEach((id) => {\n if (store.query(hasEntity(id as TEntity[IdKey]))) {\n selectedValues.push(id);\n }\n });\n this.selectValue = selectedValues;\n this.cdr.detectChanges();\n }\n } else {\n if (store.query(hasEntity(entityId as TEntity[IdKey]))) {\n // if (this._entities.has(entityId)) {\n this.selectValue = entityId;\n if (this.filterStr) {\n this.filterStr = '';\n // this.filterNonGroupedEntities(entities, this.filterStr);\n }\n this.cdr.detectChanges();\n }\n }\n }\n\n registerOnChange(fn: any): void {\n this.onChanged = fn;\n }\n\n registerOnTouched(fn: any): void {\n this.onTouched = fn;\n }\n\n @Input()\n get entities(): TEntity[] {\n return this.getEntities();\n }\n\n set entities(items: TEntity[]) {\n this.setEntities(items);\n }\n\n @Input()\n get value(): string | number | string[] | number[] {\n return this.selectValue;\n }\n set value(val: string | number | string[] | number[]) {\n this.selectValue = val;\n this.stateChanges.next();\n }\n get shouldLabelFloat() {\n return this.focused || !this.empty;\n }\n\n @Input('aria-describedby') userAriaDescribedBy!: string;\n\n @Input()\n get placeholder(): string {\n return this._placeholder;\n }\n set placeholder(value: string) {\n this._placeholder = value;\n this.stateChanges.next();\n }\n\n @Input()\n get required() {\n return (\n this._required ??\n this.ngControl?.control?.hasValidator(Validators.required)\n );\n }\n set required(req: boolean) {\n this._required = coerceBooleanProperty(req);\n this.stateChanges.next();\n }\n // Deliberately 'undefined' so that `get required()` will return the state\n // from ngControl's validators.\n private _required!: boolean;\n\n @Input()\n get disabled(): boolean {\n return this._disabled ?? this.ngControl?.control?.disabled;\n }\n set disabled(value: BooleanInput) {\n const disabled = coerceBooleanProperty(value);\n if (disabled !== this._disabled) {\n this.setDisabledState(disabled);\n this.stateChanges.next();\n }\n }\n // Same as `_required`, deliberately `undefined` by default.\n private _disabled!: boolean;\n\n get empty() {\n return !this.value;\n }\n\n get errorState(): boolean {\n return !!this.ngControl?.invalid && this.touched;\n }\n\n onFocusIn(event: FocusEvent) {\n if (!this.focused) {\n this.focused = true;\n this.stateChanges.next();\n }\n }\n\n onFocusOut(event: FocusEvent) {\n if (\n !this._elementRef.nativeElement.contains(event.relatedTarget as Element)\n ) {\n this.touched = true;\n this.focused = false;\n this.onTouched();\n this.stateChanges.next();\n }\n }\n\n setDescribedByIds(ids: string[]) {}\n\n onContainerClick(event: MouseEvent) {\n if ((event.target as Element).tagName.toLowerCase() != 'mat-select') {\n this._elementRef.nativeElement.querySelector('mat-select').focus();\n }\n }\n\n setDisabledState(isDisabled: boolean): void {\n this._disabled = isDisabled;\n const matSelect = this.matSelect();\n if (matSelect) {\n matSelect.setDisabledState(isDisabled);\n this.cdr.detectChanges();\n }\n }\n\n onSelectOpened(ev: any) {\n // Store the current select value so that we can restore it if user\n // eventually selects 'New Item' option.\n this.lastSelectValue = this.selectValue;\n // If values have not been loaded from remote, trigger a load.\n if (this.totalEntitiesAtRemote() === 0) {\n // first load\n this.loadNextPage();\n }\n }\n\n onSelectionChange(ev: MatSelectChange) {\n // console.log('SelectionChange - sel:', ev);\n if (Array.isArray(ev.value)) {\n this.selectValue = ev.value;\n this.onTouched();\n this.onChanged(ev.value);\n const selectedEntities: TEntity[] = ev.value.map((id) =>\n this.store.query(getEntity(id))\n ) as TEntity[];\n this.selectionChange.emit(selectedEntities);\n } else {\n if (ev.value !== '0') {\n this.selectValue = ev.value;\n this.onTouched();\n this.onChanged(ev.value);\n this.selectionChange.emit(this.store.query(getEntity(ev.value)));\n } else {\n // New Item activated, return value to previous value. We track\n // previous value via 'lastSelectValue' member which is updated\n // whenever the select is opened.\n if (this.ngControl) {\n this.ngControl.control?.setValue(this.lastSelectValue);\n }\n ev.source.value = this.lastSelectValue;\n this.createNewItemSelected.emit();\n this.cdr.detectChanges();\n }\n }\n }\n\n /**\n * Wrapper to filter entities based on whether grouping is enabled or not.\n * Calls one of the two filtering methods -- filterGroupedEntities() or\n * filterNonGroupedEntities().\n * @param entities\n * @param filterStr\n * @returns\n */\n filterEntities(entities: TEntity[], filterStr: string) {\n this.searching = true;\n let retval: number | undefined;\n if (this._group()) {\n this.filterGroupedEntities(entities, filterStr);\n } else {\n this.filterNonGroupedEntities(entities, filterStr);\n }\n this.searching = false;\n }\n\n /**\n * Filters the entities based on the search string.\n * @param search The search string to filter entities.\n * @returns The number of entities in the filtered result set or undefined.\n */\n filterNonGroupedEntities(entities: TEntity[], search: string) {\n const searchLwr = search.toLocaleLowerCase();\n if (!search) {\n this.filteredValues.next(entities.slice());\n } else {\n const filteredEntities = entities.filter((member) => {\n const filterFn = this.filterFn();\n if (filterFn) {\n return filterFn(member, search);\n }\n const labelFn = this._entityLabelFn();\n return labelFn(member).toLocaleLowerCase().includes(searchLwr);\n });\n this.filteredValues.next(filteredEntities);\n }\n }\n\n /**\n * Filtering grouped entities logic works like this. If the search string\n * matches a group label, the entire group is to be included in the results.\n * However, if the search string only matches certain entities, only those\n * groups are to be included and within those groups, only entities whose\n * label matches the search string are to be included in the result set.\n * @param search\n * @returns number of groups in the filtered result set.\n */\n filterGroupedEntities(entities: TEntity[], search: string) {\n const searchLwr = search.toLocaleLowerCase();\n // First filter entities by the search string, if it's specified\n let filteredEntities: TEntity[];\n if (!search) {\n filteredEntities = entities;\n } else {\n filteredEntities = entities.filter((member) => {\n const filterFn = this.filterFn();\n if (filterFn) {\n return filterFn(member, search);\n }\n const labelFn = this._entityLabelFn();\n return labelFn(member).toLocaleLowerCase().includes(searchLwr);\n });\n }\n this.filteredGroupedValues.next(this.groupEntities(filteredEntities));\n }\n\n /**\n * Helper to arrange the given array of entities into groups based on the\n * groupByFn or groupOptionsKey. groupByFn takes precedence over\n * groupOptionsKey.\n * @param entities\n * @returns EntityGroup<TEntity>[]\n */\n protected groupEntities(entities: TEntity[]): EntityGroup<TEntity>[] {\n let groupByFn!: (entity: TEntity) => string;\n if (this.groupByFn()) {\n groupByFn = this.groupByFn()!;\n } else if (this.groupOptionsKey()) {\n groupByFn = (entity: TEntity) => {\n const key = this.groupOptionsKey()!;\n return (entity as any)[key] ?? '???';\n };\n }\n\n const groupedEntitiesMap = new Map<string | number, TEntity[]>();\n entities.forEach((entity) => {\n const groupId = groupByFn!(entity);\n if (!groupedEntitiesMap.has(groupId)) {\n groupedEntitiesMap.set(groupId, []);\n }\n groupedEntitiesMap.get(groupId)!.push(entity);\n });\n let entityGroups: EntityGroup<TEntity>[] = [];\n groupedEntitiesMap.forEach((entities, groupId) => {\n entityGroups.push({\n label: String(groupId),\n entities,\n });\n });\n return entityGroups;\n }\n\n // private existsInCache() {\n // const cacheKey = this.getCacheKey();\n // if (cacheKey) {\n // return SPMatSelectEntityComponent._entitiesCache.has(cacheKey);\n // }\n // return false;\n // }\n\n // private getCacheKey() {\n // if (typeof this.url() !== 'function') {\n // let params!: HttpParams;\n // if (this.httpParams) {\n // params = new HttpParams({\n // fromString: this.httpParams.toString(),\n // });\n // } else {\n // params = new HttpParams();\n // }\n // // params = params.set('paginate', false)\n // return `${this.url}?${params.toString()}`;\n // }\n // return ''; // empty string evalutes to boolean(false)\n // }\n\n // private getFromCache() {\n // const cacheKey = this.getCacheKey();\n // if (cacheKey && SPMatSelectEntityComponent._entitiesCache.has(cacheKey)) {\n // return SPMatSelectEntityComponent._entitiesCache.get(cacheKey)\n // ?.entities as TEntity[];\n // }\n // return [];\n // }\n\n // private addToCache(entities: TEntity[]) {\n // const cacheKey = this.getCacheKey();\n // if (cacheKey) {\n // if (!SPMatSelectEntityComponent._entitiesCache.has(cacheKey)) {\n // SPMatSelectEntityComponent._entitiesCache.set(cacheKey, {\n // refCount: 0,\n // entities,\n // });\n // }\n // const cacheEntry =\n // SPMatSelectEntityComponent._entitiesCache.get(cacheKey);\n // cacheEntry!.refCount += 1;\n // }\n // }\n\n // private removeFromCache() {\n // const cacheKey = this.getCacheKey();\n // if (cacheKey) {\n // const cacheEntry =\n // SPMatSelectEntityComponent._entitiesCache.get(cacheKey);\n // if (cacheEntry) {\n // cacheEntry!.refCount -= 1;\n // if (cacheEntry.refCount <= 0) {\n // SPMatSelectEntityComponent._entitiesCache.delete(cacheKey);\n // }\n // }\n // }\n // }\n\n private getHttpReqContext() {\n const context = new HttpContext();\n const entityName = this.entityName;\n context.set(SP_MAT_SELECT_ENTITY_HTTP_CONTEXT, {\n entityName: this.entityName(),\n entityNamePlural: this._pluralEntityName(),\n endpoint: this.url() as string,\n });\n return context;\n }\n\n /**\n * If more entities are available, load the next page of entities.\n * This method is triggered when user scrolls to the bottom of the options\n * list. Well almost to the bottom of the options list. :)\n */\n onInfiniteScroll() {\n if (this.hasMore() && !this.loading()) {\n this.loadNextPage();\n }\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"smallpearl-ngx-helper-mat-select-entity.mjs","sources":["../../../../projects/smallpearl/ngx-helper/mat-select-entity/src/mat-select-entity.component.ts","../../../../projects/smallpearl/ngx-helper/mat-select-entity/smallpearl-ngx-helper-mat-select-entity.ts"],"sourcesContent":["import { BooleanInput, coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { CommonModule, NgTemplateOutlet } from '@angular/common';\nimport {\n HttpContext,\n HttpContextToken\n} from '@angular/common/http';\nimport {\n AfterViewInit,\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n computed,\n ElementRef,\n EventEmitter,\n HostBinding,\n inject,\n input,\n Input,\n OnDestroy,\n OnInit,\n Output,\n TemplateRef,\n viewChild,\n} from '@angular/core';\nimport {\n ControlValueAccessor,\n FormsModule,\n NgControl,\n ReactiveFormsModule,\n Validators,\n} from '@angular/forms';\nimport { MatButtonModule } from '@angular/material/button';\nimport {\n MAT_FORM_FIELD,\n MatFormFieldControl,\n} from '@angular/material/form-field';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatProgressSpinnerModule } from '@angular/material/progress-spinner';\nimport {\n MatSelect,\n MatSelectChange,\n MatSelectModule,\n} from '@angular/material/select';\nimport {\n provideTranslocoScope,\n TranslocoModule,\n TranslocoService,\n} from '@jsverse/transloco';\nimport { getEntity, hasEntity, selectAllEntities, upsertEntities } from '@ngneat/elf-entities';\nimport {\n SPPagedEntityLoader\n} from '@smallpearl/ngx-helper/entities';\nimport {\n SPMatEntityListPaginator,\n SPPageParams,\n} from '@smallpearl/ngx-helper/mat-entity-list';\nimport { MatSelectInfiniteScrollDirective } from '@smallpearl/ngx-helper/mat-select-infinite-scroll';\nimport { NgxMatSelectSearchModule } from 'ngx-mat-select-search';\nimport {\n combineLatest,\n debounceTime,\n distinctUntilChanged,\n Observable,\n startWith,\n Subject,\n takeUntil,\n tap\n} from 'rxjs';\n\n\nexport interface SPMatSelectEntityHttpContext {\n entityName: string;\n entityNamePlural: string;\n endpoint: string;\n}\n\nexport const SP_MAT_SELECT_ENTITY_HTTP_CONTEXT =\n new HttpContextToken<SPMatSelectEntityHttpContext>(() => ({\n entityName: '',\n entityNamePlural: '',\n endpoint: '',\n }));\n\n// Internal type to represent a group of entities. Used when grouping is enabled.\ntype EntityGroup<TEntity> = {\n label: string;\n entities: TEntity[];\n};\n\nexport type SPMatSelectEntityResponseParser = <\n TEntity extends { [P in IdKey]: PropertyKey },\n IdKey extends string = 'id'\n>(\n response: any\n) => Array<TEntity>;\n\n// Default paginator implementation. This can handle dynamic-rest and DRF\n// native pagination schemes. It also has a fallback to handle response conists\n// of an array of entities.\nclass DefaultPaginator implements SPMatEntityListPaginator {\n getRequestPageParams(\n endpoint: string,\n page: number,\n pageSize: number\n ): SPPageParams {\n return {\n page: page + 1,\n pageSize,\n };\n }\n\n parseRequestResponse<\n TEntity extends { [P in IdKey]: PropertyKey },\n IdKey extends string = 'id'\n >(\n entityName: string,\n entityNamePlural: string,\n endpoint: string,\n params: SPPageParams,\n resp: any\n ) {\n if (Array.isArray(resp)) {\n return {\n total: resp.length,\n entities: resp,\n };\n }\n\n if (typeof resp === 'object') {\n const keys = Object.keys(resp);\n // Handle dynamic-rest sideloaded response\n // Rudimentary sideloaded response support. This should work for most\n // of the sideloaded responses where the main entities are stored\n // under the plural entity name key and resp['meta'] object contains\n // the total count.\n if (\n keys.includes(entityNamePlural) &&\n Array.isArray(resp[entityNamePlural])\n ) {\n let total = resp[entityNamePlural].length;\n if (\n keys.includes('meta') &&\n typeof resp['meta'] === 'object' &&\n typeof resp['meta']['total'] === 'number'\n ) {\n total = resp['meta']['total'];\n }\n return {\n total,\n entities: resp[entityNamePlural],\n };\n }\n\n // Handle django-rest-framework style response\n if (keys.includes('results') && Array.isArray(resp['results'])) {\n let total = resp['results'].length;\n if (keys.includes('count') && typeof resp['count'] === 'number') {\n total = resp['count'];\n }\n return {\n total,\n entities: resp['results'],\n };\n }\n\n // Finally, look for \"items\" key\n if (keys.includes('items') && Array.isArray(resp['items'])) {\n return {\n total: resp['items'].length,\n entities: resp['items'],\n };\n }\n }\n\n return {\n total: 0,\n entities: [],\n };\n }\n}\n\n/**\n * This is a generic component to display a <mat-select> for a FK field\n * where the select's options are dynamically loaded from the server using\n * the given url (or URL). The objects thus retrieved should have a\n * unique 'id' field that will be used as the value of each `option` element.\n * Therefore upon selection of an `option` element, the `select` value will\n * be set to the object's `id` property. By default 'id' is used as its id,\n * but this can be customized by specifying the `idKey' property value.\n */\n@Component({\n selector: 'sp-mat-select-entity',\n template: `\n <div\n *transloco=\"let t; scope: 'sp-mat-select-entity'\"\n (focusin)=\"onFocusIn($event)\"\n (focusout)=\"onFocusOut($event)\"\n role=\"group\"\n [attr.aria-labelledby]=\"_formField?.getLabelId()\"\n >\n <mat-select\n [placeholder]=\"placeholder\"\n (opened)=\"onSelectOpened($event)\"\n (selectionChange)=\"onSelectionChange($event)\"\n [multiple]=\"multiple()\"\n [(ngModel)]=\"selectValue\"\n msInfiniteScroll\n (infiniteScroll)=\"onInfiniteScroll()\"\n >\n <mat-select-trigger>\n {{ selectTriggerValue }}\n @if (selectTriggerValueAsArray.length > 1) {\n <span class=\"addl-selection-count\">\n (+{{ selectTriggerValueAsArray.length - 1 }})\n </span>\n }\n </mat-select-trigger>\n\n <mat-option [disabled]=\"totalEntitiesCount() === 0\">\n <ngx-mat-select-search\n class=\"flex-grow-1\"\n [(ngModel)]=\"filterStr\"\n (ngModelChange)=\"this.filter$.next($event)\"\n [placeholderLabel]=\"\n searchText() ? searchText() : t('spMatSelectEntity.search')\n \"\n [noEntriesFoundLabel]=\"\n notFoundText() ? notFoundText() : t('spMatSelectEntity.notFound')\n \"\n [searching]=\"searching\"\n >\n </ngx-mat-select-search>\n </mat-option>\n\n <ng-template #defaultOptionLabelTemplate let-entity>\n {{ _entityLabelFn()(entity) }}\n </ng-template>\n @if (!_group()) { @if (filteredValues | async; as entities) { @for\n (entity of entities; track entityId(entity)) {\n <mat-option class=\"sel-entity-option\" [value]=\"entityId(entity)\">\n <ng-container\n *ngTemplateOutlet=\"\n optionLabelTemplate() || defaultOptionLabelTemplate;\n context: { $implicit: entity }\n \"\n ></ng-container>\n </mat-option>\n } } } @else { @if (filteredGroupedValues | async; as groups) { @for\n (group of groups; track group.label) {\n <mat-optgroup [label]=\"group.label\">\n @for (entity of group.entities; track entityId(entity)) {\n <mat-option class=\"sel-entity-option\" [value]=\"entityId(entity)\">\n <ng-container\n *ngTemplateOutlet=\"\n optionLabelTemplate() || defaultOptionLabelTemplate;\n context: { $implicit: entity }\n \"\n ></ng-container>\n </mat-option>\n }\n </mat-optgroup>\n } } }\n\n <!--\n Create New option is displayed only if there is a filter string.\n The logic behind this behavior being that user searches for a matching\n item and when not finding one, would like to add a new one.\n -->\n @if (inlineNew() && loaded() && (filterStr.length > 0 || totalEntitiesAtRemote() === 0)) {\n <mat-option\n class=\"add-item-option\"\n value=\"0\"\n (click)=\"$event.stopPropagation()\"\n >⊕\n {{\n this.createNewText()\n ? this.createNewText()\n : t('spMatSelectEntity.createNew', {\n item: this._capitalizedEntityName()\n })\n }}\n </mat-option>\n } @if (loading()) {\n <div class=\"loading-wrapper\">\n <mat-progress-spinner\n diameter=\"24\"\n mode=\"indeterminate\"\n ></mat-progress-spinner>\n </div>\n }\n </mat-select>\n </div>\n `,\n styles: [\n `\n .add-item-option {\n padding-top: 2px;\n border-top: 1px solid var(--mat-sys-outline);\n }\n .addl-selection-count {\n opacity: 0.75;\n font-size: 0.8em;\n }\n .loading-wrapper {\n display: flex;\n justify-content: center;\n padding: 8px 0;\n }\n `,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [\n CommonModule,\n NgTemplateOutlet,\n FormsModule,\n ReactiveFormsModule,\n MatSelectModule,\n MatButtonModule,\n MatIconModule,\n MatProgressSpinnerModule,\n TranslocoModule,\n NgxMatSelectSearchModule,\n MatSelectInfiniteScrollDirective,\n ],\n providers: [\n provideTranslocoScope('sp-mat-select-entity'),\n { provide: MatFormFieldControl, useExisting: SPMatSelectEntityComponent },\n ],\n})\nexport class SPMatSelectEntityComponent<\n TEntity extends { [P in IdKey]: PropertyKey },\n IdKey extends string = 'id'\n >\n extends SPPagedEntityLoader<TEntity, IdKey>\n implements\n OnInit,\n OnDestroy,\n AfterViewInit,\n ControlValueAccessor,\n MatFormFieldControl<string | number | string[] | number[]>\n{\n // We cache the entities that we fetch from remote here. Cache is indexed\n // by the endpoint. Each endpoint also keeps a refCount, which is incremented\n // for each instance of the component using the same endpoint. When this\n // refcount reaches 0, the endpoint is removed from the cache.\n //\n // This mechanism is to suppress multiple fetches from the remote from the\n // same endpoint as that can occur if a form has multiple instances of\n // this component with the same url.\n // static _entitiesCache = new Map<\n // string,\n // { refCount: number; entities: Array<any> }\n // >();\n\n //**** OPTIONAL ATTRIBUTES ****//\n\n // Entity label function - function that takes an entity object and returns\n // a string label for it. If not specified, a default label function is used\n // that returns the value of 'name' or 'label' or 'title' property. If\n // none of these properties are present, the entity's id is returned as\n // string.\n labelFn = input<(entity: TEntity) => string>();\n\n // Entity filter function - return a boolean if the entity is to be included\n // in the filtered entities list.\n filterFn = input<(entity: TEntity, search: string) => boolean>();\n\n // Set to true to show \"Add { item }\" option in the select dropdown.\n // Selecting this option, will emit `createNewItemSelected` event.\n inlineNew = input<boolean>(false);\n\n // Set to true to allow multiple option selection. The returned value\n // would be an array of entity ids.\n multiple = input<boolean>(false);\n\n /**\n * The entity key name that is used to classify entities into groups.\n * Entities with the same key value will be grouped together. If this is\n * specified, grouping will be enabled.\n * @see groupByFn\n */\n groupOptionsKey = input<string>();\n\n /**\n * A function that takes a TEntity and returns the group id (string)\n * that the entity belongs to. If this is specified, grouping of entities\n * in the select will be enabled. This takes precedence over\n * `groupOptionsKey`.\n * @see groupOptionsKey\n */\n groupByFn = input<(entity: TEntity) => string>();\n\n @Output() selectionChange = new EventEmitter<TEntity | TEntity[]>();\n @Output() createNewItemSelected = new EventEmitter<void>();\n\n // i18n localization support toallow per component customization of\n // some strings used.\n readonly searchText = input<string>();\n readonly notFoundText = input<string>();\n readonly createNewText = input<string>();\n\n controlType = 'sp-mat-select-entity';\n\n /**\n * Template for the option label. If not provided, the default label\n * function will be used. Option label is what is placed inside the\n * <mat-option> tag. The template gets an implicit 'entity' variable\n * in the context, value for which is the entity object.\n *\n * For example:\n * ```\n * <sp-mat-select-entity\n * [url]=\"'/api/v1/customers/'\"\n * [labelFn]=\"entity => entity.name\"\n * [optionLabelTemplate]=\"optionLabelTemplate\"\n * ></sp-mat-select-entity>\n * <ng-template #optionLabelTemplate let-entity>\n * {{ entity.name }} - {{ entity.description }}\n * </ng-template>\n * ```\n */\n optionLabelTemplate = input<TemplateRef<any>>();\n\n // a computed version of labelFn that provides a default implementation\n protected _entityLabelFn = computed<(entity: TEntity) => string>(() => {\n const fn = this.labelFn();\n if (fn) {\n return fn;\n }\n return (entity: TEntity) => {\n return (\n (entity as any)['name'] ||\n (entity as any)['label'] ||\n (entity as any)['title'] ||\n String((entity as any)[this.idKey()])\n );\n };\n });\n\n // Whether to group options. Grouping is enabled when either groupOptionsKey\n // or groupByFn is specified.\n protected _group = computed<boolean>(() => {\n return !!this.groupOptionsKey() || !!this.groupByFn();\n });\n\n protected _groupEntitiesKey = computed<string>(() => {\n const groupOptionsKey = this.groupOptionsKey();\n return groupOptionsKey\n ? groupOptionsKey\n : this.entityName()\n ? this._pluralEntityName()\n : 'items';\n });\n\n // For the global paginator. We'll abstract this into an independent\n // configuration that can be shared across both mat-entity-list and\n // mat-select-entity later.\n // entityListConfig = getEntityListConfig();\n\n // protected _paginator = computed<SPMatEntityListPaginator>(() => {\n // const paginator = this.paginator();\n // const entityListConfigPaginator = this.entityListConfig\n // ?.paginator as SPMatEntityListPaginator;\n // return paginator\n // ? paginator\n // : entityListConfigPaginator ?? new DefaultPaginator();\n // });\n\n stateChanges = new Subject<void>();\n focused = false;\n touched = false;\n\n selectValue!: string | number | string[] | number[];\n // To store initial value when writeValue() is called before entities are\n // loaded, either by entities() input or via paged loader. This is especially\n // necessary when the elf store uses an idKey other than 'id'.\n _initialValue: string | number | string[] | number[] | undefined = undefined;\n\n // For storing last select value, which we use to restore the select's value\n // to when New Item is selected. This ensures that when New Item is selected,\n // the select's value remains the same. If the newly created item is to be\n // set as the select's value, the corresponding TEntity has to be added\n // to _entities (via addEntity()) and then selected by setting the\n // corresponding formControl's value to the entity's id.\n lastSelectValue!: string | number | string[] | number[];\n searching = false;\n filterStr: string = '';\n\n filter$ = new Subject<string>();\n\n // ControlValueAccessor callbacks\n onChanged = (_: any) => {};\n onTouched = () => {};\n\n // @ViewChild(MatSelect) matSelect!: MatSelect;\n matSelect = viewChild(MatSelect);\n\n filteredValues = new Subject<TEntity[]>();\n filteredGroupedValues = new Subject<EntityGroup<TEntity>[]>();\n\n destroy = new Subject<void>();\n\n static nextId = 0;\n @HostBinding() id = `sp-select-entity-${SPMatSelectEntityComponent.nextId++}`;\n private _placeholder!: string;\n //protected http = inject(HttpClient);\n protected cdr = inject(ChangeDetectorRef);\n protected _elementRef = inject(ElementRef<HTMLElement>);\n protected _formField = inject(MAT_FORM_FIELD, { optional: true });\n public ngControl = inject(NgControl, { optional: true });\n transloco = inject(TranslocoService);\n\n // pagedEntityLoader!: SPPagedEntityLoader<TEntity, IdKey>;\n\n constructor() {\n super();\n if (this.ngControl != null) {\n this.ngControl.valueAccessor = this;\n }\n }\n\n /**\n * Conditions for loading entities:\n *\n * 1. When the select is opened, if entities have not already been loaded.\n * 2. When the search string changes.\n * 3. When the scroll reaches the bottom and more entities are available\n * to be loaded.\n *\n * We need to create an 'observer-loop' that can handle the above.\n */\n\n ngOnInit() {\n this.startLoader();\n // A rudimentary mechanism to detect which of the two observables\n // emitted the latest value. We reset this array to 'false' after\n // processing every combined emission.\n const emittedObservable = [false, false];\n const store$ = this.store.pipe(selectAllEntities());\n const filter$ = this.filter$.pipe(\n startWith(''),\n distinctUntilChanged(),\n debounceTime(400)\n );\n\n const emittedStatusObservable = (obs: Observable<any>, index: number) =>\n obs.pipe(tap(() => (emittedObservable[index] = true)));\n\n // We need to determine if the emission is owing to a change in\n // filterStr or a change in the entities in pagedEntityLoader.store$.\n //\n // 1. If entities in pagedEntityLoader.store$ have changed, we just need\n // to filter the entities in local store using the current filterStr.\n // 2. If filterStr has changed, there are two cases to handle:-\n // a. If all entities have been loaded, we don't need to reload\n // entities. Instead we just have to filter the entities in\n // local store using the filterStr.\n // b. If all entities have not been loaded, we trigger a server\n // load with the new filterStr as the search param.\n //\n // The following logic implements the above.\n combineLatest([\n emittedStatusObservable(store$, 0),\n emittedStatusObservable(filter$, 1),\n ])\n .pipe(\n takeUntil(this.destroy),\n tap(([entities, filterStr]) => {\n if (emittedObservable.every((eo) => eo)) {\n // initial emission. This can be combined with the case immediately\n // below it. But we keep it separate for clarity.\n emittedObservable[0] = emittedObservable[1] = false;\n this.filterEntities(entities, filterStr);\n } else if (emittedObservable[0]) {\n emittedObservable[0] = false;\n this.filterEntities(entities, filterStr);\n } else {\n emittedObservable[1] = false;\n if (this.allEntitiesLoaded()) {\n this.filterEntities(entities, filterStr);\n } else {\n this.setSearchParamValue(filterStr);\n // This will cause an emission from store$ observable as the\n // 'forceRefresh=true' arg causes the store to be reset.\n this.loadNextPage(true);\n }\n }\n })\n )\n .subscribe();\n\n if (this._initialValue !== undefined) {\n this.writeValue(this._initialValue);\n this._initialValue = undefined;\n }\n }\n\n ngOnDestroy(): void {\n this.destroy.next();\n this.destroy.complete();\n this.stopLoader();\n // this.removeFromCache();\n this.stateChanges.complete();\n }\n\n ngAfterViewInit(): void {\n // I'm not sure this is how this logic is right, but this seems to work.\n // if (this.ngControl && this.ngControl.control?.validator) {\n // const validator = this.ngControl.control.validator;\n // const res = validator(this.ngControl.control);\n // if (res && res['required']) {\n // this.required = true;\n // }\n // }\n // load first page\n // this.loadMoreEntities();\n }\n\n addEntity(entity: TEntity) {\n this.store.update(upsertEntities(entity));\n this.cdr.detectChanges();\n }\n\n get selectTriggerValue() {\n if (this.selectValue) {\n const firstSelected = Array.isArray(this.selectValue)\n ? this.selectValue[0]\n : this.selectValue;\n const selectedEntity = this.getEntity(firstSelected as TEntity[IdKey]);\n return selectedEntity ? this._entityLabelFn()(selectedEntity) : '';\n }\n return '';\n }\n\n get selectTriggerValueAsArray() {\n return Array.isArray(this.selectValue)\n ? (this.selectValue as Array<string | number>)\n : [];\n }\n\n entityId(entity: TEntity) {\n return (entity as any)[this.idKey()];\n }\n\n writeValue(entityId: string | number | string[] | number[]): void {\n // If the component has not yet started (calling startLoader()), we store\n // the initial value in _initialValue and return. The actual setting of\n // the value will happen after startLoader() is called from ngOnInit().\n if (!this.hasStarted()) {\n this._initialValue = entityId;\n return;\n }\n\n const store = this.store;\n const entities = this.getEntities();\n if (Array.isArray(entityId)) {\n if (this.multiple()) {\n const selectedValues: any[] = [];\n entityId.forEach((id) => {\n if (store.query(hasEntity(id as TEntity[IdKey]))) {\n selectedValues.push(id);\n }\n });\n this.selectValue = selectedValues;\n this.cdr.detectChanges();\n }\n } else {\n if (store.query(hasEntity(entityId as TEntity[IdKey]))) {\n // if (this._entities.has(entityId)) {\n this.selectValue = entityId;\n if (this.filterStr) {\n this.filterStr = '';\n // this.filterNonGroupedEntities(entities, this.filterStr);\n }\n this.cdr.detectChanges();\n }\n }\n }\n\n registerOnChange(fn: any): void {\n this.onChanged = fn;\n }\n\n registerOnTouched(fn: any): void {\n this.onTouched = fn;\n }\n\n @Input()\n get entities(): TEntity[] {\n return this.getEntities();\n }\n\n set entities(items: TEntity[]) {\n this.setEntities(items);\n }\n\n @Input()\n get value(): string | number | string[] | number[] {\n return this.selectValue;\n }\n set value(val: string | number | string[] | number[]) {\n this.selectValue = val;\n this.stateChanges.next();\n }\n get shouldLabelFloat() {\n return this.focused || !this.empty;\n }\n\n @Input('aria-describedby') userAriaDescribedBy!: string;\n\n @Input()\n get placeholder(): string {\n return this._placeholder;\n }\n set placeholder(value: string) {\n this._placeholder = value;\n this.stateChanges.next();\n }\n\n @Input()\n get required() {\n return (\n this._required ??\n this.ngControl?.control?.hasValidator(Validators.required)\n );\n }\n set required(req: boolean) {\n this._required = coerceBooleanProperty(req);\n this.stateChanges.next();\n }\n // Deliberately 'undefined' so that `get required()` will return the state\n // from ngControl's validators.\n private _required!: boolean;\n\n @Input()\n get disabled(): boolean {\n return this._disabled ?? this.ngControl?.control?.disabled;\n }\n set disabled(value: BooleanInput) {\n const disabled = coerceBooleanProperty(value);\n if (disabled !== this._disabled) {\n this.setDisabledState(disabled);\n this.stateChanges.next();\n }\n }\n // Same as `_required`, deliberately `undefined` by default.\n private _disabled!: boolean;\n\n get empty() {\n return !this.value;\n }\n\n get errorState(): boolean {\n return !!this.ngControl?.invalid && this.touched;\n }\n\n onFocusIn(event: FocusEvent) {\n if (!this.focused) {\n this.focused = true;\n this.stateChanges.next();\n }\n }\n\n onFocusOut(event: FocusEvent) {\n if (\n !this._elementRef.nativeElement.contains(event.relatedTarget as Element)\n ) {\n this.touched = true;\n this.focused = false;\n this.onTouched();\n this.stateChanges.next();\n }\n }\n\n setDescribedByIds(ids: string[]) {}\n\n onContainerClick(event: MouseEvent) {\n if ((event.target as Element).tagName.toLowerCase() != 'mat-select') {\n this._elementRef.nativeElement.querySelector('mat-select').focus();\n }\n }\n\n setDisabledState(isDisabled: boolean): void {\n this._disabled = isDisabled;\n const matSelect = this.matSelect();\n if (matSelect) {\n matSelect.setDisabledState(isDisabled);\n this.cdr.detectChanges();\n }\n }\n\n onSelectOpened(ev: any) {\n // Store the current select value so that we can restore it if user\n // eventually selects 'New Item' option.\n this.lastSelectValue = this.selectValue;\n // If values have not been loaded from remote, trigger a load.\n if (this.totalEntitiesAtRemote() === 0) {\n // first load\n this.loadNextPage();\n }\n }\n\n onSelectionChange(ev: MatSelectChange) {\n // console.log('SelectionChange - sel:', ev);\n if (Array.isArray(ev.value)) {\n this.selectValue = ev.value;\n this.onTouched();\n this.onChanged(ev.value);\n const selectedEntities: TEntity[] = ev.value.map((id) =>\n this.store.query(getEntity(id))\n ) as TEntity[];\n this.selectionChange.emit(selectedEntities);\n } else {\n if (ev.value !== '0') {\n this.selectValue = ev.value;\n this.onTouched();\n this.onChanged(ev.value);\n this.selectionChange.emit(this.store.query(getEntity(ev.value)));\n } else {\n // New Item activated, return value to previous value. We track\n // previous value via 'lastSelectValue' member which is updated\n // whenever the select is opened.\n if (this.ngControl) {\n this.ngControl.control?.setValue(this.lastSelectValue);\n }\n ev.source.value = this.lastSelectValue;\n this.createNewItemSelected.emit();\n this.cdr.detectChanges();\n }\n }\n }\n\n /**\n * Wrapper to filter entities based on whether grouping is enabled or not.\n * Calls one of the two filtering methods -- filterGroupedEntities() or\n * filterNonGroupedEntities().\n * @param entities\n * @param filterStr\n * @returns\n */\n filterEntities(entities: TEntity[], filterStr: string) {\n this.searching = true;\n let retval: number | undefined;\n if (this._group()) {\n this.filterGroupedEntities(entities, filterStr);\n } else {\n this.filterNonGroupedEntities(entities, filterStr);\n }\n this.searching = false;\n }\n\n /**\n * Filters the entities based on the search string.\n * @param search The search string to filter entities.\n * @returns The number of entities in the filtered result set or undefined.\n */\n filterNonGroupedEntities(entities: TEntity[], search: string) {\n const searchLwr = search.toLocaleLowerCase();\n if (!search) {\n this.filteredValues.next(entities.slice());\n } else {\n const filteredEntities = entities.filter((member) => {\n const filterFn = this.filterFn();\n if (filterFn) {\n return filterFn(member, search);\n }\n const labelFn = this._entityLabelFn();\n return labelFn(member).toLocaleLowerCase().includes(searchLwr);\n });\n this.filteredValues.next(filteredEntities);\n }\n }\n\n /**\n * Filtering grouped entities logic works like this. If the search string\n * matches a group label, the entire group is to be included in the results.\n * However, if the search string only matches certain entities, only those\n * groups are to be included and within those groups, only entities whose\n * label matches the search string are to be included in the result set.\n * @param search\n * @returns number of groups in the filtered result set.\n */\n filterGroupedEntities(entities: TEntity[], search: string) {\n const searchLwr = search.toLocaleLowerCase();\n // First filter entities by the search string, if it's specified\n let filteredEntities: TEntity[];\n if (!search) {\n filteredEntities = entities;\n } else {\n filteredEntities = entities.filter((member) => {\n const filterFn = this.filterFn();\n if (filterFn) {\n return filterFn(member, search);\n }\n const labelFn = this._entityLabelFn();\n return labelFn(member).toLocaleLowerCase().includes(searchLwr);\n });\n }\n this.filteredGroupedValues.next(this.groupEntities(filteredEntities));\n }\n\n /**\n * Helper to arrange the given array of entities into groups based on the\n * groupByFn or groupOptionsKey. groupByFn takes precedence over\n * groupOptionsKey.\n * @param entities\n * @returns EntityGroup<TEntity>[]\n */\n protected groupEntities(entities: TEntity[]): EntityGroup<TEntity>[] {\n let groupByFn!: (entity: TEntity) => string;\n if (this.groupByFn()) {\n groupByFn = this.groupByFn()!;\n } else if (this.groupOptionsKey()) {\n groupByFn = (entity: TEntity) => {\n const key = this.groupOptionsKey()!;\n return (entity as any)[key] ?? '???';\n };\n }\n\n const groupedEntitiesMap = new Map<string | number, TEntity[]>();\n entities.forEach((entity) => {\n const groupId = groupByFn!(entity);\n if (!groupedEntitiesMap.has(groupId)) {\n groupedEntitiesMap.set(groupId, []);\n }\n groupedEntitiesMap.get(groupId)!.push(entity);\n });\n let entityGroups: EntityGroup<TEntity>[] = [];\n groupedEntitiesMap.forEach((entities, groupId) => {\n entityGroups.push({\n label: String(groupId),\n entities,\n });\n });\n return entityGroups;\n }\n\n // private existsInCache() {\n // const cacheKey = this.getCacheKey();\n // if (cacheKey) {\n // return SPMatSelectEntityComponent._entitiesCache.has(cacheKey);\n // }\n // return false;\n // }\n\n // private getCacheKey() {\n // if (typeof this.url() !== 'function') {\n // let params!: HttpParams;\n // if (this.httpParams) {\n // params = new HttpParams({\n // fromString: this.httpParams.toString(),\n // });\n // } else {\n // params = new HttpParams();\n // }\n // // params = params.set('paginate', false)\n // return `${this.url}?${params.toString()}`;\n // }\n // return ''; // empty string evalutes to boolean(false)\n // }\n\n // private getFromCache() {\n // const cacheKey = this.getCacheKey();\n // if (cacheKey && SPMatSelectEntityComponent._entitiesCache.has(cacheKey)) {\n // return SPMatSelectEntityComponent._entitiesCache.get(cacheKey)\n // ?.entities as TEntity[];\n // }\n // return [];\n // }\n\n // private addToCache(entities: TEntity[]) {\n // const cacheKey = this.getCacheKey();\n // if (cacheKey) {\n // if (!SPMatSelectEntityComponent._entitiesCache.has(cacheKey)) {\n // SPMatSelectEntityComponent._entitiesCache.set(cacheKey, {\n // refCount: 0,\n // entities,\n // });\n // }\n // const cacheEntry =\n // SPMatSelectEntityComponent._entitiesCache.get(cacheKey);\n // cacheEntry!.refCount += 1;\n // }\n // }\n\n // private removeFromCache() {\n // const cacheKey = this.getCacheKey();\n // if (cacheKey) {\n // const cacheEntry =\n // SPMatSelectEntityComponent._entitiesCache.get(cacheKey);\n // if (cacheEntry) {\n // cacheEntry!.refCount -= 1;\n // if (cacheEntry.refCount <= 0) {\n // SPMatSelectEntityComponent._entitiesCache.delete(cacheKey);\n // }\n // }\n // }\n // }\n\n private getHttpReqContext() {\n const context = new HttpContext();\n const entityName = this.entityName;\n context.set(SP_MAT_SELECT_ENTITY_HTTP_CONTEXT, {\n entityName: this.entityName(),\n entityNamePlural: this._pluralEntityName(),\n endpoint: this.url() as string,\n });\n return context;\n }\n\n /**\n * If more entities are available, load the next page of entities.\n * This method is triggered when user scrolls to the bottom of the options\n * list. Well almost to the bottom of the options list. :)\n */\n onInfiniteScroll() {\n if (this.hasMore() && !this.loading()) {\n this.loadNextPage();\n }\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "path": "src/assets/i18n/"
7
7
  }
8
8
  ],
9
- "version": "0.33.8",
9
+ "version": "0.33.9",
10
10
  "peerDependencies": {
11
11
  "@angular/common": "^19.1.0",
12
12
  "@angular/core": "^19.1.0",
@@ -48,9 +48,9 @@
48
48
  "types": "./entities/index.d.ts",
49
49
  "default": "./fesm2022/smallpearl-ngx-helper-entities.mjs"
50
50
  },
51
- "./locale": {
52
- "types": "./locale/index.d.ts",
53
- "default": "./fesm2022/smallpearl-ngx-helper-locale.mjs"
51
+ "./hover-dropdown": {
52
+ "types": "./hover-dropdown/index.d.ts",
53
+ "default": "./fesm2022/smallpearl-ngx-helper-hover-dropdown.mjs"
54
54
  },
55
55
  "./entity-field": {
56
56
  "types": "./entity-field/index.d.ts",
@@ -64,9 +64,9 @@
64
64
  "types": "./mat-busy-wheel/index.d.ts",
65
65
  "default": "./fesm2022/smallpearl-ngx-helper-mat-busy-wheel.mjs"
66
66
  },
67
- "./hover-dropdown": {
68
- "types": "./hover-dropdown/index.d.ts",
69
- "default": "./fesm2022/smallpearl-ngx-helper-hover-dropdown.mjs"
67
+ "./locale": {
68
+ "types": "./locale/index.d.ts",
69
+ "default": "./fesm2022/smallpearl-ngx-helper-locale.mjs"
70
70
  },
71
71
  "./mat-context-menu": {
72
72
  "types": "./mat-context-menu/index.d.ts",
@@ -80,14 +80,14 @@
80
80
  "types": "./mat-entity-list/index.d.ts",
81
81
  "default": "./fesm2022/smallpearl-ngx-helper-mat-entity-list.mjs"
82
82
  },
83
- "./mat-form-error": {
84
- "types": "./mat-form-error/index.d.ts",
85
- "default": "./fesm2022/smallpearl-ngx-helper-mat-form-error.mjs"
86
- },
87
83
  "./mat-file-input": {
88
84
  "types": "./mat-file-input/index.d.ts",
89
85
  "default": "./fesm2022/smallpearl-ngx-helper-mat-file-input.mjs"
90
86
  },
87
+ "./mat-form-error": {
88
+ "types": "./mat-form-error/index.d.ts",
89
+ "default": "./fesm2022/smallpearl-ngx-helper-mat-form-error.mjs"
90
+ },
91
91
  "./mat-select-entity": {
92
92
  "types": "./mat-select-entity/index.d.ts",
93
93
  "default": "./fesm2022/smallpearl-ngx-helper-mat-select-entity.mjs"