@smallpearl/ngx-helper 0.29.26 → 0.29.29

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.
@@ -2,7 +2,7 @@ import * as i0 from '@angular/core';
2
2
  import { InjectionToken, input, EventEmitter, computed, Component, ChangeDetectionStrategy, Optional, Inject, Self, ViewChild, Input, Output, HostBinding } from '@angular/core';
3
3
  import { coerceBooleanProperty } from '@angular/cdk/coercion';
4
4
  import * as i3 from '@angular/common';
5
- import { CommonModule } from '@angular/common';
5
+ import { CommonModule, NgTemplateOutlet } from '@angular/common';
6
6
  import * as i1 from '@angular/common/http';
7
7
  import { HttpContextToken, HttpParams, HttpContext } from '@angular/common/http';
8
8
  import * as i2 from '@angular/forms';
@@ -155,6 +155,25 @@ class SPMatSelectEntityComponent {
155
155
  searchText;
156
156
  notFoundText;
157
157
  addItemText;
158
+ /**
159
+ * Template for the option label. If not provided, the default label
160
+ * function will be used. Option label is what is placed inside the
161
+ * <mat-option> tag. The template gets an implicit 'entity' variable
162
+ * in the context, value for which is the entity object.
163
+ *
164
+ * For example:
165
+ * ```
166
+ * <sp-mat-select-entity
167
+ * [url]="'/api/v1/customers/'"
168
+ * [entityLabelFn]="entity => entity.name"
169
+ * [optionLabelTemplate]="optionLabelTemplate"
170
+ * ></sp-mat-select-entity>
171
+ * <ng-template #optionLabelTemplate let-entity>
172
+ * {{ entity.name }} - {{ entity.description }}
173
+ * </ng-template>
174
+ * ```
175
+ */
176
+ optionLabelTemplate = input();
158
177
  _sideloadDataKey = computed(() => {
159
178
  if (this.sideloadDataKey()) {
160
179
  return this.sideloadDataKey();
@@ -249,7 +268,7 @@ class SPMatSelectEntityComponent {
249
268
  this.notFoundText = config.i18n.notFound;
250
269
  }
251
270
  if (!this.addItemText) {
252
- this.addItemText = config.i18n.addItem.replace(/\{\{\s*item\s*}}/, this.entityName ?? "**Item");
271
+ this.addItemText = config.i18n.addItem.replace(/\{\{\s*item\s*}}/, this.entityName ?? '**Item');
253
272
  }
254
273
  }
255
274
  addEntity(entity) {
@@ -260,14 +279,18 @@ class SPMatSelectEntityComponent {
260
279
  }
261
280
  get selectTriggerValue() {
262
281
  if (this.selectValue) {
263
- const firstSelected = Array.isArray(this.selectValue) ? this.selectValue[0] : this.selectValue;
282
+ const firstSelected = Array.isArray(this.selectValue)
283
+ ? this.selectValue[0]
284
+ : this.selectValue;
264
285
  const selectedEntity = this._entities.get(firstSelected);
265
286
  return selectedEntity ? this.entityLabelFn(selectedEntity) : '';
266
287
  }
267
288
  return '';
268
289
  }
269
290
  get selectTriggerValueAsArray() {
270
- return Array.isArray(this.selectValue) ? this.selectValue : [];
291
+ return Array.isArray(this.selectValue)
292
+ ? this.selectValue
293
+ : [];
271
294
  }
272
295
  entityId(entity) {
273
296
  return entity[this.idKey];
@@ -276,7 +299,7 @@ class SPMatSelectEntityComponent {
276
299
  if (Array.isArray(entityId)) {
277
300
  if (this.multiple) {
278
301
  const selectedValues = [];
279
- entityId.forEach(id => {
302
+ entityId.forEach((id) => {
280
303
  if (this._entities.has(id)) {
281
304
  selectedValues.push(id);
282
305
  }
@@ -307,17 +330,17 @@ class SPMatSelectEntityComponent {
307
330
  }
308
331
  set entities(items) {
309
332
  if (!this.group) {
310
- items.forEach(item => {
333
+ items.forEach((item) => {
311
334
  this._entities.set(item[this.idKey], item);
312
335
  });
313
336
  }
314
337
  else {
315
338
  this._groupedEntities = items;
316
- this._groupedEntities.forEach(group => {
339
+ this._groupedEntities.forEach((group) => {
317
340
  const key = this.groupEntitiesKey();
318
341
  const groupEntities = group[key];
319
342
  group['__items__'] = groupEntities;
320
- groupEntities.forEach(item => {
343
+ groupEntities.forEach((item) => {
321
344
  this._entities.set(item[this.idKey], item);
322
345
  });
323
346
  });
@@ -342,7 +365,8 @@ class SPMatSelectEntityComponent {
342
365
  this.stateChanges.next();
343
366
  }
344
367
  get required() {
345
- return this._required ?? this.ngControl?.control?.hasValidator(Validators.required);
368
+ return (this._required ??
369
+ this.ngControl?.control?.hasValidator(Validators.required));
346
370
  }
347
371
  set required(req) {
348
372
  this._required = coerceBooleanProperty(req);
@@ -356,7 +380,6 @@ class SPMatSelectEntityComponent {
356
380
  }
357
381
  set disabled(value) {
358
382
  const disabled = coerceBooleanProperty(value);
359
- ;
360
383
  if (disabled !== this._disabled) {
361
384
  this.setDisabledState(disabled);
362
385
  this.stateChanges.next();
@@ -421,7 +444,7 @@ class SPMatSelectEntityComponent {
421
444
  this.selectValue = ev.value;
422
445
  this.onTouched();
423
446
  this.onChanged(ev.value);
424
- const selectedEntities = ev.value.map(id => this._entities.get(id));
447
+ const selectedEntities = ev.value.map((id) => this._entities.get(id));
425
448
  this.selectionChange.emit(selectedEntities);
426
449
  }
427
450
  else {
@@ -458,7 +481,9 @@ class SPMatSelectEntityComponent {
458
481
  if (this.entityFilterFn) {
459
482
  return this.entityFilterFn(member, search);
460
483
  }
461
- return this.entityLabelFn(member).toLocaleLowerCase().includes(searchLwr);
484
+ return this.entityLabelFn(member)
485
+ .toLocaleLowerCase()
486
+ .includes(searchLwr);
462
487
  }));
463
488
  }
464
489
  }
@@ -483,15 +508,15 @@ class SPMatSelectEntityComponent {
483
508
  }
484
509
  else {
485
510
  const groupEntitiesKey = this.groupEntitiesKey();
486
- const groups = this._groupedEntities.map(ge => {
511
+ const groups = this._groupedEntities.map((ge) => {
487
512
  const label = this.groupLabel(ge);
488
513
  if (label.toLocaleLowerCase().includes(searchLwr)) {
489
514
  return { ...ge };
490
515
  }
491
516
  else {
492
- const groupEntities = ge.__items__?.filter(e => this.entityLabelFn(e).toLocaleLowerCase().includes(searchLwr));
517
+ const groupEntities = ge.__items__?.filter((e) => this.entityLabelFn(e).toLocaleLowerCase().includes(searchLwr));
493
518
  const ret = {
494
- ...ge
519
+ ...ge,
495
520
  };
496
521
  ret['__items__'] = groupEntities ?? [];
497
522
  return ret;
@@ -518,7 +543,7 @@ class SPMatSelectEntityComponent {
518
543
  let params;
519
544
  if (this.httpParams) {
520
545
  params = new HttpParams({
521
- fromString: this.httpParams.toString()
546
+ fromString: this.httpParams.toString(),
522
547
  });
523
548
  }
524
549
  else {
@@ -549,7 +574,8 @@ class SPMatSelectEntityComponent {
549
574
  Array.isArray(entities['results'])) {
550
575
  entities = entities['results'];
551
576
  }
552
- else if ( // sideloaded response, where entities are usually provided in 'entityName'
577
+ else if (
578
+ // sideloaded response, where entities are usually provided in 'entityName'
553
579
  this._sideloadDataKey() &&
554
580
  !Array.isArray(entities) &&
555
581
  typeof entities === 'object' &&
@@ -590,8 +616,11 @@ class SPMatSelectEntityComponent {
590
616
  return group[this.groupEntitiesKey()] ?? [];
591
617
  }
592
618
  groupEntitiesKey() {
593
- return this.groupOptionsKey ? this.groupOptionsKey
594
- : (this.entityName ? plural(this.entityName.toLocaleLowerCase()) : 'items');
619
+ return this.groupOptionsKey
620
+ ? this.groupOptionsKey
621
+ : this.entityName
622
+ ? plural(this.entityName.toLocaleLowerCase())
623
+ : 'items';
595
624
  }
596
625
  existsInCache() {
597
626
  const cacheKey = this.getCacheKey();
@@ -605,7 +634,7 @@ class SPMatSelectEntityComponent {
605
634
  let params;
606
635
  if (this.httpParams) {
607
636
  params = new HttpParams({
608
- fromString: this.httpParams.toString()
637
+ fromString: this.httpParams.toString(),
609
638
  });
610
639
  }
611
640
  else {
@@ -619,7 +648,8 @@ class SPMatSelectEntityComponent {
619
648
  getFromCache() {
620
649
  const cacheKey = this.getCacheKey();
621
650
  if (cacheKey && SPMatSelectEntityComponent._entitiesCache.has(cacheKey)) {
622
- return SPMatSelectEntityComponent._entitiesCache.get(cacheKey)?.entities;
651
+ return SPMatSelectEntityComponent._entitiesCache.get(cacheKey)
652
+ ?.entities;
623
653
  }
624
654
  return [];
625
655
  }
@@ -627,7 +657,10 @@ class SPMatSelectEntityComponent {
627
657
  const cacheKey = this.getCacheKey();
628
658
  if (cacheKey) {
629
659
  if (!SPMatSelectEntityComponent._entitiesCache.has(cacheKey)) {
630
- SPMatSelectEntityComponent._entitiesCache.set(cacheKey, { refCount: 0, entities });
660
+ SPMatSelectEntityComponent._entitiesCache.set(cacheKey, {
661
+ refCount: 0,
662
+ entities,
663
+ });
631
664
  }
632
665
  const cacheEntry = SPMatSelectEntityComponent._entitiesCache.get(cacheKey);
633
666
  cacheEntry.refCount += 1;
@@ -651,12 +684,14 @@ class SPMatSelectEntityComponent {
651
684
  context.set(SP_MAT_SELECT_ENTITY_HTTP_CONTEXT, {
652
685
  entityName: this.entityName ?? '',
653
686
  entityNamePlural: this.entityName ? plural(this.entityName) : '',
654
- endpoint: this.url
687
+ endpoint: this.url,
655
688
  });
656
689
  return context;
657
690
  }
658
691
  /** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.6", ngImport: i0, type: SPMatSelectEntityComponent, deps: [{ token: i1.HttpClient }, { token: i0.ChangeDetectorRef }, { token: i0.ElementRef }, { token: i0.Injector }, { token: MAT_FORM_FIELD, optional: true }, { token: i2.NgControl, optional: true, self: true }, { token: SP_MAT_SELECT_ENTITY_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Component });
659
- /** @nocollapse */ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.6", type: SPMatSelectEntityComponent, isStandalone: true, selector: "sp-mat-select-entity", inputs: { entityLabelFn: { classPropertyName: "entityLabelFn", publicName: "entityLabelFn", isSignal: false, isRequired: true, transformFunction: null }, entityFilterFn: { classPropertyName: "entityFilterFn", publicName: "entityFilterFn", isSignal: false, isRequired: false, transformFunction: null }, idKey: { classPropertyName: "idKey", publicName: "idKey", isSignal: false, isRequired: false, transformFunction: null }, url: { classPropertyName: "url", publicName: "url", isSignal: false, isRequired: false, transformFunction: null }, httpParams: { classPropertyName: "httpParams", publicName: "httpParams", isSignal: false, isRequired: false, transformFunction: null }, loadFromRemoteFn: { classPropertyName: "loadFromRemoteFn", publicName: "loadFromRemoteFn", isSignal: false, isRequired: false, transformFunction: null }, inlineNew: { classPropertyName: "inlineNew", publicName: "inlineNew", isSignal: false, isRequired: false, transformFunction: null }, entityName: { classPropertyName: "entityName", publicName: "entityName", isSignal: false, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: false, isRequired: false, transformFunction: null }, group: { classPropertyName: "group", publicName: "group", isSignal: false, isRequired: false, transformFunction: null }, groupOptionsKey: { classPropertyName: "groupOptionsKey", publicName: "groupOptionsKey", isSignal: false, isRequired: false, transformFunction: null }, groupLabelFn: { classPropertyName: "groupLabelFn", publicName: "groupLabelFn", isSignal: false, isRequired: false, transformFunction: null }, sideloadDataKey: { classPropertyName: "sideloadDataKey", publicName: "sideloadDataKey", isSignal: true, isRequired: false, transformFunction: null }, responseParserFn: { classPropertyName: "responseParserFn", publicName: "responseParserFn", isSignal: true, isRequired: false, transformFunction: null }, searchText: { classPropertyName: "searchText", publicName: "searchText", isSignal: false, isRequired: false, transformFunction: null }, notFoundText: { classPropertyName: "notFoundText", publicName: "notFoundText", isSignal: false, isRequired: false, transformFunction: null }, addItemText: { classPropertyName: "addItemText", publicName: "addItemText", isSignal: false, isRequired: false, transformFunction: null }, entities: { classPropertyName: "entities", publicName: "entities", isSignal: false, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: false, isRequired: false, transformFunction: null }, userAriaDescribedBy: { classPropertyName: "userAriaDescribedBy", publicName: "aria-describedby", isSignal: false, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: false, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: false, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { selectionChange: "selectionChange", createNewItemSelected: "createNewItemSelected" }, host: { properties: { "id": "this.id" } }, providers: [{ provide: MatFormFieldControl, useExisting: SPMatSelectEntityComponent }], viewQueries: [{ propertyName: "matSel", first: true, predicate: MatSelect, descendants: true }, { propertyName: "matSelect", first: true, predicate: MatSelect, descendants: true }], ngImport: i0, template: `
692
+ /** @nocollapse */ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.6", type: SPMatSelectEntityComponent, isStandalone: true, selector: "sp-mat-select-entity", inputs: { entityLabelFn: { classPropertyName: "entityLabelFn", publicName: "entityLabelFn", isSignal: false, isRequired: true, transformFunction: null }, entityFilterFn: { classPropertyName: "entityFilterFn", publicName: "entityFilterFn", isSignal: false, isRequired: false, transformFunction: null }, idKey: { classPropertyName: "idKey", publicName: "idKey", isSignal: false, isRequired: false, transformFunction: null }, url: { classPropertyName: "url", publicName: "url", isSignal: false, isRequired: false, transformFunction: null }, httpParams: { classPropertyName: "httpParams", publicName: "httpParams", isSignal: false, isRequired: false, transformFunction: null }, loadFromRemoteFn: { classPropertyName: "loadFromRemoteFn", publicName: "loadFromRemoteFn", isSignal: false, isRequired: false, transformFunction: null }, inlineNew: { classPropertyName: "inlineNew", publicName: "inlineNew", isSignal: false, isRequired: false, transformFunction: null }, entityName: { classPropertyName: "entityName", publicName: "entityName", isSignal: false, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: false, isRequired: false, transformFunction: null }, group: { classPropertyName: "group", publicName: "group", isSignal: false, isRequired: false, transformFunction: null }, groupOptionsKey: { classPropertyName: "groupOptionsKey", publicName: "groupOptionsKey", isSignal: false, isRequired: false, transformFunction: null }, groupLabelFn: { classPropertyName: "groupLabelFn", publicName: "groupLabelFn", isSignal: false, isRequired: false, transformFunction: null }, sideloadDataKey: { classPropertyName: "sideloadDataKey", publicName: "sideloadDataKey", isSignal: true, isRequired: false, transformFunction: null }, responseParserFn: { classPropertyName: "responseParserFn", publicName: "responseParserFn", isSignal: true, isRequired: false, transformFunction: null }, searchText: { classPropertyName: "searchText", publicName: "searchText", isSignal: false, isRequired: false, transformFunction: null }, notFoundText: { classPropertyName: "notFoundText", publicName: "notFoundText", isSignal: false, isRequired: false, transformFunction: null }, addItemText: { classPropertyName: "addItemText", publicName: "addItemText", isSignal: false, isRequired: false, transformFunction: null }, optionLabelTemplate: { classPropertyName: "optionLabelTemplate", publicName: "optionLabelTemplate", isSignal: true, isRequired: false, transformFunction: null }, entities: { classPropertyName: "entities", publicName: "entities", isSignal: false, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: false, isRequired: false, transformFunction: null }, userAriaDescribedBy: { classPropertyName: "userAriaDescribedBy", publicName: "aria-describedby", isSignal: false, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: false, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: false, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { selectionChange: "selectionChange", createNewItemSelected: "createNewItemSelected" }, host: { properties: { "id": "this.id" } }, providers: [
693
+ { provide: MatFormFieldControl, useExisting: SPMatSelectEntityComponent },
694
+ ], viewQueries: [{ propertyName: "matSel", first: true, predicate: MatSelect, descendants: true }, { propertyName: "matSelect", first: true, predicate: MatSelect, descendants: true }], ngImport: i0, template: `
660
695
  <mat-select
661
696
  [placeholder]="placeholder"
662
697
  (opened)="onSelectOpened($event)"
@@ -667,7 +702,9 @@ class SPMatSelectEntityComponent {
667
702
  <mat-select-trigger>
668
703
  {{ selectTriggerValue }}
669
704
  @if (selectTriggerValueAsArray.length > 1) {
670
- <span class="addl-selection-count"> (+{{ selectTriggerValueAsArray.length - 1 }}) </span>
705
+ <span class="addl-selection-count">
706
+ (+{{ selectTriggerValueAsArray.length - 1 }})
707
+ </span>
671
708
  }
672
709
  </mat-select-trigger>
673
710
 
@@ -683,31 +720,50 @@ class SPMatSelectEntityComponent {
683
720
  </mat-option>
684
721
 
685
722
  <ng-container *ngIf="!group; else groupedOptions">
686
- <span *ngIf="(filteredValues | async) as entities">
687
- <mat-option class="sel-entity-option" *ngFor="let entity of entities" [value]="entityId(entity)">
723
+ <span *ngIf="filteredValues | async as entities">
724
+ <ng-template #defaultOptionLabelTemplate let-entity>
688
725
  {{ entityLabelFn(entity) }}
726
+ </ng-template>
727
+ @for (entity of entities; track entityId(entity)) {
728
+ <mat-option class="sel-entity-option" [value]="entityId(entity)">
729
+ <ng-container
730
+ *ngTemplateOutlet="
731
+ optionLabelTemplate() || defaultOptionLabelTemplate;
732
+ context: { $implicit: entity }
733
+ "
734
+ ></ng-container>
689
735
  </mat-option>
736
+ }
737
+
738
+ <!-- <mat-option class="sel-entity-option" *ngFor="let entity of entities" [value]="entityId(entity)">
739
+ {{ entityLabelFn(entity) }}
740
+ </mat-option> -->
690
741
  </span>
691
742
  </ng-container>
692
743
  <ng-template #groupedOptions>
693
- <span *ngIf="(filteredGroupedValues | async) as groups">
744
+ <span *ngIf="filteredGroupedValues | async as groups">
694
745
  @for (group of groups; track groupLabel(group)) {
695
- <mat-optgroup [label]="groupLabel(group)">
696
- @for (entity of group.__items__; track entityId(entity)) {
697
- <mat-option class="sel-entity-option" [value]="entityId(entity)">
698
- {{ entityLabelFn(entity) }}
699
- </mat-option>
700
- }
701
- </mat-optgroup>
746
+ <mat-optgroup [label]="groupLabel(group)">
747
+ @for (entity of group.__items__; track entityId(entity)) {
748
+
749
+ <mat-option class="sel-entity-option" [value]="entityId(entity)">
750
+ {{ entityLabelFn(entity) }}
751
+ </mat-option>
752
+ }
753
+ </mat-optgroup>
702
754
  }
703
755
  </span>
704
756
  </ng-template>
705
757
 
706
- <mat-option *ngIf="!multiple && inlineNew" class="add-item-option" value="0" (click)="$event.stopPropagation()"
758
+ <mat-option
759
+ *ngIf="!multiple && inlineNew"
760
+ class="add-item-option"
761
+ value="0"
762
+ (click)="$event.stopPropagation()"
707
763
  >⊕ {{ addItemText }}</mat-option
708
764
  >
709
765
  </mat-select>
710
- `, isInline: true, styles: [".add-item-option{padding-top:2px;border-top:1px solid gray}.addl-selection-count{opacity:.75;font-size:.8em}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i4.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "directive", type: i4.MatSelectTrigger, selector: "mat-select-trigger" }, { kind: "component", type: i5.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i5.MatOptgroup, selector: "mat-optgroup", inputs: ["label", "disabled"], exportAs: ["matOptgroup"] }, { kind: "ngmodule", type: NgxMatSelectSearchModule }, { kind: "component", type: i6.MatSelectSearchComponent, selector: "ngx-mat-select-search", inputs: ["placeholderLabel", "type", "closeIcon", "closeSvgIcon", "noEntriesFoundLabel", "clearSearchInput", "searching", "disableInitialFocus", "enableClearOnEscapePressed", "preventHomeEndKeyPropagation", "disableScrollToActiveOnOptionsChanged", "ariaLabel", "showToggleAllCheckbox", "toggleAllCheckboxChecked", "toggleAllCheckboxIndeterminate", "toggleAllCheckboxTooltipMessage", "toggleAllCheckboxTooltipPosition", "hideClearSearchButton", "alwaysRestoreSelectedOptionsMulti", "recreateValuesArray"], outputs: ["toggleAll"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
766
+ `, isInline: true, styles: [".add-item-option{padding-top:2px;border-top:1px solid gray}.addl-selection-count{opacity:.75;font-size:.8em}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i4.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "directive", type: i4.MatSelectTrigger, selector: "mat-select-trigger" }, { kind: "component", type: i5.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i5.MatOptgroup, selector: "mat-optgroup", inputs: ["label", "disabled"], exportAs: ["matOptgroup"] }, { kind: "ngmodule", type: NgxMatSelectSearchModule }, { kind: "component", type: i6.MatSelectSearchComponent, selector: "ngx-mat-select-search", inputs: ["placeholderLabel", "type", "closeIcon", "closeSvgIcon", "noEntriesFoundLabel", "clearSearchInput", "searching", "disableInitialFocus", "enableClearOnEscapePressed", "preventHomeEndKeyPropagation", "disableScrollToActiveOnOptionsChanged", "ariaLabel", "showToggleAllCheckbox", "toggleAllCheckboxChecked", "toggleAllCheckboxIndeterminate", "toggleAllCheckboxTooltipMessage", "toggleAllCheckboxTooltipPosition", "hideClearSearchButton", "alwaysRestoreSelectedOptionsMulti", "recreateValuesArray"], outputs: ["toggleAll"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
711
767
  }
712
768
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.6", ngImport: i0, type: SPMatSelectEntityComponent, decorators: [{
713
769
  type: Component,
@@ -722,7 +778,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.6", ngImpor
722
778
  <mat-select-trigger>
723
779
  {{ selectTriggerValue }}
724
780
  @if (selectTriggerValueAsArray.length > 1) {
725
- <span class="addl-selection-count"> (+{{ selectTriggerValueAsArray.length - 1 }}) </span>
781
+ <span class="addl-selection-count">
782
+ (+{{ selectTriggerValueAsArray.length - 1 }})
783
+ </span>
726
784
  }
727
785
  </mat-select-trigger>
728
786
 
@@ -738,31 +796,59 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.6", ngImpor
738
796
  </mat-option>
739
797
 
740
798
  <ng-container *ngIf="!group; else groupedOptions">
741
- <span *ngIf="(filteredValues | async) as entities">
742
- <mat-option class="sel-entity-option" *ngFor="let entity of entities" [value]="entityId(entity)">
799
+ <span *ngIf="filteredValues | async as entities">
800
+ <ng-template #defaultOptionLabelTemplate let-entity>
743
801
  {{ entityLabelFn(entity) }}
802
+ </ng-template>
803
+ @for (entity of entities; track entityId(entity)) {
804
+ <mat-option class="sel-entity-option" [value]="entityId(entity)">
805
+ <ng-container
806
+ *ngTemplateOutlet="
807
+ optionLabelTemplate() || defaultOptionLabelTemplate;
808
+ context: { $implicit: entity }
809
+ "
810
+ ></ng-container>
744
811
  </mat-option>
812
+ }
813
+
814
+ <!-- <mat-option class="sel-entity-option" *ngFor="let entity of entities" [value]="entityId(entity)">
815
+ {{ entityLabelFn(entity) }}
816
+ </mat-option> -->
745
817
  </span>
746
818
  </ng-container>
747
819
  <ng-template #groupedOptions>
748
- <span *ngIf="(filteredGroupedValues | async) as groups">
820
+ <span *ngIf="filteredGroupedValues | async as groups">
749
821
  @for (group of groups; track groupLabel(group)) {
750
- <mat-optgroup [label]="groupLabel(group)">
751
- @for (entity of group.__items__; track entityId(entity)) {
752
- <mat-option class="sel-entity-option" [value]="entityId(entity)">
753
- {{ entityLabelFn(entity) }}
754
- </mat-option>
755
- }
756
- </mat-optgroup>
822
+ <mat-optgroup [label]="groupLabel(group)">
823
+ @for (entity of group.__items__; track entityId(entity)) {
824
+
825
+ <mat-option class="sel-entity-option" [value]="entityId(entity)">
826
+ {{ entityLabelFn(entity) }}
827
+ </mat-option>
828
+ }
829
+ </mat-optgroup>
757
830
  }
758
831
  </span>
759
832
  </ng-template>
760
833
 
761
- <mat-option *ngIf="!multiple && inlineNew" class="add-item-option" value="0" (click)="$event.stopPropagation()"
834
+ <mat-option
835
+ *ngIf="!multiple && inlineNew"
836
+ class="add-item-option"
837
+ value="0"
838
+ (click)="$event.stopPropagation()"
762
839
  >⊕ {{ addItemText }}</mat-option
763
840
  >
764
841
  </mat-select>
765
- `, changeDetection: ChangeDetectionStrategy.OnPush, imports: [CommonModule, FormsModule, ReactiveFormsModule, MatSelectModule, NgxMatSelectSearchModule], providers: [{ provide: MatFormFieldControl, useExisting: SPMatSelectEntityComponent }], styles: [".add-item-option{padding-top:2px;border-top:1px solid gray}.addl-selection-count{opacity:.75;font-size:.8em}\n"] }]
842
+ `, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
843
+ CommonModule,
844
+ NgTemplateOutlet,
845
+ FormsModule,
846
+ ReactiveFormsModule,
847
+ MatSelectModule,
848
+ NgxMatSelectSearchModule,
849
+ ], providers: [
850
+ { provide: MatFormFieldControl, useExisting: SPMatSelectEntityComponent },
851
+ ], styles: [".add-item-option{padding-top:2px;border-top:1px solid gray}.addl-selection-count{opacity:.75;font-size:.8em}\n"] }]
766
852
  }], ctorParameters: () => [{ type: i1.HttpClient }, { type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: i0.Injector }, { type: i7.MatFormField, decorators: [{
767
853
  type: Optional
768
854
  }, {
@@ -1 +1 @@
1
- {"version":3,"file":"smallpearl-ngx-helper-mat-select-entity.mjs","sources":["../../../../projects/smallpearl/ngx-helper/mat-select-entity/src/providers.ts","../../../../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 { InjectionToken } from '@angular/core';\n\nexport interface SPMatSelectEntityConfig {\n i18n: {\n search: string;\n notFound: string;\n // Any embedded \"{{ item }}\" in the addItem string will be replaced\n // with entityName property value. If entityName is not specified\n // \"Item\" will be used as the value for \"{{ item }}\".\n addItem: string;\n };\n}\n\nexport const SP_MAT_SELECT_ENTITY_CONFIG = new InjectionToken<SPMatSelectEntityConfig>(\n 'SPMatSelectEntityConfig'\n );\n","import { BooleanInput, coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { CommonModule } from '@angular/common';\nimport { HttpClient, HttpContext, HttpContextToken, HttpParams } from '@angular/common/http';\nimport {\n AfterViewInit,\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n computed,\n ElementRef,\n EventEmitter,\n HostBinding,\n Inject,\n Injector,\n input,\n Input,\n OnDestroy,\n OnInit,\n Optional,\n Output,\n Self,\n ViewChild\n} from '@angular/core';\nimport { ControlValueAccessor, FormsModule, NgControl, ReactiveFormsModule, Validators } from '@angular/forms';\nimport { MAT_FORM_FIELD, MatFormField, MatFormFieldControl } from '@angular/material/form-field';\nimport { MatSelect, MatSelectChange, MatSelectModule } from '@angular/material/select';\nimport { NgxMatSelectSearchModule } from 'ngx-mat-select-search';\nimport {\n BehaviorSubject,\n combineLatest,\n debounceTime,\n Observable,\n of,\n Subject,\n switchMap,\n takeUntil,\n tap\n} from 'rxjs';\nimport { SP_MAT_SELECT_ENTITY_CONFIG, SPMatSelectEntityConfig } from './providers';\nimport { getNgxHelperConfig } from '@smallpearl/ngx-helper/core';\nimport { plural } from 'pluralize';\nimport { camelCase } from 'lodash';\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\nconst DEFAULT_SP_MAT_SELECT_ENTITY_CONFIG: SPMatSelectEntityConfig =\n {\n i18n: {\n search: 'Search',\n notFound: 'Not found',\n addItem: 'New Item',\n },\n };\n\ntype EntityGroup<T> = {\n id?: PropertyKey;\n name?: string;\n label?: string;\n description?: string;\n items?: T[];\n __items__?: T[]; // for internal use\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/**\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 <mat-select\n [placeholder]=\"placeholder\"\n (opened)=\"onSelectOpened($event)\"\n (selectionChange)=\"onSelectionChange($event)\"\n [multiple]=\"multiple\"\n [(ngModel)]=\"selectValue\"\n >\n <mat-select-trigger>\n {{ selectTriggerValue }}\n @if (selectTriggerValueAsArray.length > 1) {\n <span class=\"addl-selection-count\"> (+{{ selectTriggerValueAsArray.length - 1 }}) </span>\n }\n </mat-select-trigger>\n\n <mat-option>\n <ngx-mat-select-search\n [(ngModel)]=\"filterStr\"\n (ngModelChange)=\"this.filter$.next($event)\"\n [placeholderLabel]=\"searchText\"\n [noEntriesFoundLabel]=\"notFoundText\"\n [searching]=\"searching\"\n >\n </ngx-mat-select-search>\n </mat-option>\n\n <ng-container *ngIf=\"!group; else groupedOptions\">\n <span *ngIf=\"(filteredValues | async) as entities\">\n <mat-option class=\"sel-entity-option\" *ngFor=\"let entity of entities\" [value]=\"entityId(entity)\">\n {{ entityLabelFn(entity) }}\n </mat-option>\n </span>\n </ng-container>\n <ng-template #groupedOptions>\n <span *ngIf=\"(filteredGroupedValues | async) as groups\">\n @for (group of groups; track groupLabel(group)) {\n <mat-optgroup [label]=\"groupLabel(group)\">\n @for (entity of group.__items__; track entityId(entity)) {\n <mat-option class=\"sel-entity-option\" [value]=\"entityId(entity)\">\n {{ entityLabelFn(entity) }}\n </mat-option>\n }\n </mat-optgroup>\n }\n </span>\n </ng-template>\n\n <mat-option *ngIf=\"!multiple && inlineNew\" class=\"add-item-option\" value=\"0\" (click)=\"$event.stopPropagation()\"\n >⊕ {{ addItemText }}</mat-option\n >\n </mat-select>\n `,\n styles: [\n `\n .add-item-option {\n padding-top: 2px;\n border-top: 1px solid gray;\n }\n .addl-selection-count {\n opacity: 0.75;\n font-size: 0.8em;\n }\n `\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [CommonModule, FormsModule, ReactiveFormsModule, MatSelectModule, NgxMatSelectSearchModule],\n providers: [{ provide: MatFormFieldControl, useExisting: SPMatSelectEntityComponent }]\n})\nexport class SPMatSelectEntityComponent<TEntity extends { [P in IdKey]: PropertyKey }, IdKey extends string = 'id'>\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 endpoint.\n static _entitiesCache = new Map<string, { refCount: number; entities: Array<any> }>();\n\n @ViewChild(MatSelect) matSel!: MatSelect;\n\n // REQUIRED PROPERTIES //\n /**\n * Entity label function. Given an entity return its natural label\n * to display to the user.\n */\n @Input({ required: true }) entityLabelFn!: (entity: TEntity) => string;\n\n // OPTIONAL PROPERTIES //\n /**\n * Entity filter function - return a boolean if the entity is to be included\n * in the filtered entities list.\n * @param entity: TEntity object to test for 'search' string.\n * @param search - search string\n */\n @Input({ required: false }) entityFilterFn!: (entity: TEntity, search: string) => boolean;\n /**\n * Entity idKey, if idKey is different from the default 'id'.\n */\n @Input({ required: false }) idKey = 'id';\n /**\n * URL of the remote from where entities are to be loaded.\n * This won't be used if `loadFromRemoteFn` is specified.\n */\n @Input({ required: false }) url!: string;\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 */\n @Input({ required: false }) httpParams!: HttpParams;\n /**\n * Function to load entities from remote.\n */\n @Input({ required: false }) loadFromRemoteFn!: (injector: Injector) => Observable<TEntity[]>;\n\n @Input({ required: false }) inlineNew: boolean = false;\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 not an array and rather an object, 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 @Input({ required: false }) entityName!: string;\n // Set to true to allow multiple option selection. The returned value\n // would be an array of entity ids.\n @Input({ required: false }) multiple = false;\n /*\n Whether to group options using <mat-optgroup></mat-optgroup>.\n If set to true, the response from the server should be an array of\n groups of TEntity objects, where each object is of the form:\n [\n {\n id: <id>,\n name|label: <>,\n items|<plural_entityName>|<custom_key>: [\n TEntity,\n ...\n ]\n },\n ...\n ]\n */\n @Input({ required: false }) group = false;\n /**\n * The group object key name under which options are stored. Defaults to\n * 'items' or pluralized 'entityName'. Ideally the client class should\n * explicitly set this property value.\n */\n @Input({ required: false }) groupOptionsKey!: string;\n /**\n * If groupOptions = true, specify this to provide accurate label for each\n * group. If not specified, group label will be determined by looking up one\n * of the standard fields - name, label or description - whichever comes\n * first.\n */\n @Input({ required: false }) groupLabelFn!: (group: any) => string;\n /**\n * Sideload data key name.\n */\n sideloadDataKey = input<string>();\n /**\n * Parser function to return the list of entities from the GET response.\n */\n responseParserFn = input<SPMatSelectEntityResponseParser>();\n\n @Output() selectionChange = new EventEmitter<TEntity|TEntity[]>();\n @Output() createNewItemSelected = new EventEmitter<void>();\n\n // allow per component customization\n @Input() searchText!: string;\n @Input() notFoundText!: string;\n @Input() addItemText!: string;\n\n _sideloadDataKey = computed<string>(() => {\n if (this.sideloadDataKey()) {\n return this.sideloadDataKey() as string;\n }\n return this.entityName ? plural(camelCase(this.entityName)) : 'results';\n });\n\n private _entities = new Map<PropertyKey, TEntity>();\n private _groupedEntities = new Array<EntityGroup<TEntity>>();\n\n stateChanges = new Subject<void>();\n focused = false;\n touched = false;\n\n selectValue!: string | number | string[] | number[];\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 BehaviorSubject<string>('');\n // ControlValueAccessor callback\n onChanged = (_: any) => {};\n onTouched = () => {};\n @ViewChild(MatSelect) matSelect!: MatSelect;\n\n filteredValues = new Subject<TEntity[]>();\n filteredGroupedValues = new Subject<EntityGroup<TEntity>[]>();\n\n destroy = new Subject<void>();\n private loaded = false;\n private load$ = new BehaviorSubject<boolean>(false);\n\n static nextId = 0;\n @HostBinding() id = `sp-select-entity-${SPMatSelectEntityComponent.nextId++}`;\n private _placeholder!: string;\n ngxHelperConfig = getNgxHelperConfig();\n\n constructor(\n protected http: HttpClient,\n protected cdr: ChangeDetectorRef,\n protected _elementRef: ElementRef<HTMLElement>,\n protected injector: Injector,\n @Optional() @Inject(MAT_FORM_FIELD) public _formField: MatFormField,\n @Optional() @Self() public ngControl: NgControl,\n @Optional() @Inject(SP_MAT_SELECT_ENTITY_CONFIG) private config: SPMatSelectEntityConfig\n ) {\n if (this.ngControl != null) {\n this.ngControl.valueAccessor = this;\n }\n }\n\n ngOnInit() {\n this._initStrings();\n combineLatest([this.filter$.pipe(debounceTime(400)), this.load$])\n .pipe(\n takeUntil(this.destroy),\n switchMap(([str, load]) => {\n if (load && !this.loaded) {\n this.searching = true;\n this.cdr.detectChanges();\n return this.loadFromRemote();\n } else {\n return of(this.entities ?? []);\n }\n }),\n tap(() => {\n if (this.group) {\n this.filterGroupedValues(this.filterStr);\n } else {\n this.filterValues(this.filterStr);\n }\n this.cdr.detectChanges();\n })\n )\n .subscribe();\n }\n ngOnDestroy(): void {\n this.destroy.next();\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 }\n\n private _initStrings() {\n const config: SPMatSelectEntityConfig = this.config ?? DEFAULT_SP_MAT_SELECT_ENTITY_CONFIG;\n if (!this.searchText) { this.searchText = config.i18n.search; }\n if (!this.notFoundText) { this.notFoundText = config.i18n.notFound; }\n if (!this.addItemText) { this.addItemText = config.i18n.addItem.replace(/\\{\\{\\s*item\\s*}}/, this.entityName ?? \"**Item\"); }\n }\n\n addEntity(entity: TEntity) {\n this._entities.set((entity as any)[this.idKey], entity);\n // So that the newly added entity will be added to the <mat-option> list.\n this.filterValues(this.filterStr);\n this.cdr.detectChanges();\n }\n\n get selectTriggerValue() {\n if (this.selectValue) {\n const firstSelected = Array.isArray(this.selectValue) ? this.selectValue[0] : this.selectValue;\n const selectedEntity = this._entities.get(firstSelected);\n return selectedEntity ? this.entityLabelFn(selectedEntity) : '';\n }\n return '';\n }\n\n get selectTriggerValueAsArray() {\n return Array.isArray(this.selectValue) ? (this.selectValue as Array<string | number>) : [];\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 (Array.isArray(entityId)) {\n if (this.multiple) {\n const selectedValues: any[] = [];\n entityId.forEach(id => {\n if (this._entities.has(id)) {\n selectedValues.push(id);\n }\n });\n this.selectValue = selectedValues;\n this.cdr.detectChanges();\n }\n } else {\n if (this._entities.has(entityId)) {\n this.selectValue = entityId;\n if (this.filterStr) {\n this.filterStr = '';\n this.filterValues(this.filterStr);\n }\n this.cdr.detectChanges();\n }\n }\n }\n registerOnChange(fn: any): void {\n this.onChanged = fn;\n }\n registerOnTouched(fn: any): void {\n this.onTouched = fn;\n }\n\n @Input()\n get entities(): TEntity[] {\n return Array.from(this._entities.values());\n }\n\n set entities(items: TEntity[]) {\n if (!this.group) {\n items.forEach(item => {\n this._entities.set((item as any)[this.idKey], item);\n });\n } else {\n this._groupedEntities = (items as any) as EntityGroup<TEntity>[];\n this._groupedEntities.forEach(group => {\n const key = this.groupEntitiesKey();\n const groupEntities = (group as any)[key] as TEntity[];\n (group as any)['__items__'] = groupEntities;\n groupEntities.forEach(item => {\n this._entities.set((item as any)[this.idKey], item);\n });\n });\n }\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 this._required ?? this.ngControl?.control?.hasValidator(Validators.required);\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 // TODO\n return !this.value;\n }\n get errorState(): boolean {\n // TODO\n return false;\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 (!this._elementRef.nativeElement.contains(event.relatedTarget as Element)) {\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() {\n // this._focusMonitor.focusVia(this.countrySelect, 'program');\n // if (this.parts.controls.national.valid) {\n // this._focusMonitor.focusVia(this.nationalInput, 'program');\n // } else if (this.parts.controls.country.valid) {\n // this._focusMonitor.focusVia(this.nationalInput, 'program');\n // // } else if (this.parts.controls.national.valid) {\n // // this._focusMonitor.focusVia(this.nationalInput, 'program');\n // } else {\n // this._focusMonitor.focusVia(this.countrySelect, 'program');\n // }\n }\n\n setDisabledState(isDisabled: boolean): void {\n this._disabled = isDisabled;\n if (this.matSelect) {\n this.matSelect.setDisabledState(isDisabled);\n this.cdr.detectChanges();\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.loaded) {\n this.load$.next(true); // this will trigger the loadFromRemote() call.\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 => this._entities.get(id)) 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._entities.get(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 filterValues(search: string) {\n const searchLwr = search.toLocaleLowerCase();\n const entities = this.entities;\n if (!entities) {\n return;\n }\n if (!search) {\n this.filteredValues.next(entities.slice());\n } else {\n this.filteredValues.next(\n entities.filter((member) => {\n if (this.entityFilterFn) {\n return this.entityFilterFn(member, search);\n }\n return this.entityLabelFn(member).toLocaleLowerCase().includes(searchLwr);\n })\n );\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\n */\n filterGroupedValues(search: string) {\n const searchLwr = search.toLocaleLowerCase();\n const groups = this._groupedEntities;\n if (!groups) {\n return;\n }\n if (!search) {\n const groupsCopy = groups.slice();\n this.filteredGroupedValues.next(groupsCopy);\n } else {\n const groupEntitiesKey = this.groupEntitiesKey();\n const groups = this._groupedEntities.map(ge => {\n const label = this.groupLabel(ge);\n if (label.toLocaleLowerCase().includes(searchLwr)) {\n return {...ge} as EntityGroup<TEntity>;\n } else {\n const groupEntities = ge.__items__?.filter(\n e => this.entityLabelFn(e).toLocaleLowerCase().includes(searchLwr)\n );\n const ret: any = {\n ...ge\n };\n ret['__items__'] = groupEntities ?? [];\n return ret as EntityGroup<TEntity>;\n }\n });\n // filter out groups with no entities\n // console.log(`Groups: ${JSON.stringify(groups)}`);\n this.filteredGroupedValues.next(groups.filter(\n (group) =>\n Array.isArray((group as any)[groupEntitiesKey]) &&\n (group as any)['__items__'].length > 0\n ));\n }\n }\n\n loadFromRemote() {\n if (!this.url && !this.loadFromRemoteFn) {\n // If user had initialized entities, they will be dispalyed\n // in the options list. If not, options would be empty.\n return of(this.group ? this.groupEntities : this.entities);\n }\n let cacheKey!: string;\n let obs: Observable<TEntity[]>;\n if (this.loadFromRemoteFn) {\n obs = this.loadFromRemoteFn(this.injector);\n } else {\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 cacheKey = this.getCacheKey();\n if (this.existsInCache()) {\n obs = of(this.getFromCache())\n } else {\n obs = this.http.get<any>(this.url, {\n context: this.getHttpReqContext(),\n params,\n });\n }\n }\n return obs.pipe(\n tap((entities) => {\n this.searching = false; // remote loading done, will hide the loading wheel\n // Handle DRF paginated response\n const responseParserFn = this.responseParserFn();\n if (responseParserFn) {\n entities = (responseParserFn(entities) as unknown) as TEntity[];\n } else {\n if (\n !Array.isArray(entities) &&\n entities['results'] &&\n Array.isArray(entities['results'])\n ) {\n entities = entities['results'];\n } else if ( // sideloaded response, where entities are usually provided in 'entityName'\n this._sideloadDataKey() &&\n !Array.isArray(entities) &&\n typeof entities === 'object' &&\n entities[this._sideloadDataKey()] &&\n Array.isArray(entities[this._sideloadDataKey()])\n ) {\n entities = entities[this._sideloadDataKey()];\n }\n }\n if (Array.isArray(entities)) {\n this.entities = entities;\n // if (this.group) {\n // this._groupedEntities = entities as EntityGroup<TEntity>[];\n // } else {\n // this.entities = entities;\n // }\n }\n this.loaded = true;\n this.addToCache(entities);\n this.cdr.detectChanges();\n })\n );\n }\n\n groupLabel(group: EntityGroup<TEntity>): string {\n if (this.groupLabelFn) {\n return this.groupLabelFn(group);\n }\n const standardLabelFields = ['name', 'label', 'desc', 'description'];\n for (let index = 0; index < standardLabelFields.length; index++) {\n const labelField = standardLabelFields[index];\n if ((group as any)[labelField]) {\n return (group as any)[labelField];\n }\n }\n return `Group ${String(group.id)}`;\n }\n\n groupEntities(group: EntityGroup<TEntity>): TEntity[] {\n const key = this.groupEntitiesKey();\n console.log(`groupEntities - group: ${JSON.stringify(group)}, key: ${key}`);\n return (group as any)[this.groupEntitiesKey()] ?? [];\n }\n\n groupEntitiesKey() {\n return this.groupOptionsKey ? this.groupOptionsKey\n : (this.entityName ? plural(this.entityName.toLocaleLowerCase()) : 'items');\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 (!this.loadFromRemoteFn) {\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 private getFromCache() {\n const cacheKey = this.getCacheKey();\n if (cacheKey && SPMatSelectEntityComponent._entitiesCache.has(cacheKey)) {\n return SPMatSelectEntityComponent._entitiesCache.get(cacheKey)?.entities as TEntity[]\n }\n return [];\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, {refCount: 0, entities});\n }\n const cacheEntry = SPMatSelectEntityComponent._entitiesCache.get(cacheKey);\n cacheEntry!.refCount += 1;\n }\n }\n private removeFromCache() {\n const cacheKey = this.getCacheKey();\n if (cacheKey) {\n const cacheEntry = 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.entityName ? plural(this.entityName) : '',\n endpoint: this.url\n });\n return context;\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/providers.ts","../../../../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 { InjectionToken } from '@angular/core';\n\nexport interface SPMatSelectEntityConfig {\n i18n: {\n search: string;\n notFound: string;\n // Any embedded \"{{ item }}\" in the addItem string will be replaced\n // with entityName property value. If entityName is not specified\n // \"Item\" will be used as the value for \"{{ item }}\".\n addItem: string;\n };\n}\n\nexport const SP_MAT_SELECT_ENTITY_CONFIG = new InjectionToken<SPMatSelectEntityConfig>(\n 'SPMatSelectEntityConfig'\n );\n","import { BooleanInput, coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { CommonModule, NgTemplateOutlet } from '@angular/common';\nimport { HttpClient, HttpContext, HttpContextToken, HttpParams } from '@angular/common/http';\nimport {\n AfterViewInit,\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n computed,\n ElementRef,\n EventEmitter,\n HostBinding,\n Inject,\n Injector,\n input,\n Input,\n OnDestroy,\n OnInit,\n Optional,\n Output,\n Self,\n TemplateRef,\n ViewChild\n} from '@angular/core';\nimport { ControlValueAccessor, FormsModule, NgControl, ReactiveFormsModule, Validators } from '@angular/forms';\nimport { MAT_FORM_FIELD, MatFormField, MatFormFieldControl } from '@angular/material/form-field';\nimport { MatSelect, MatSelectChange, MatSelectModule } from '@angular/material/select';\nimport { NgxMatSelectSearchModule } from 'ngx-mat-select-search';\nimport {\n BehaviorSubject,\n combineLatest,\n debounceTime,\n Observable,\n of,\n Subject,\n switchMap,\n takeUntil,\n tap\n} from 'rxjs';\nimport { SP_MAT_SELECT_ENTITY_CONFIG, SPMatSelectEntityConfig } from './providers';\nimport { getNgxHelperConfig } from '@smallpearl/ngx-helper/core';\nimport { plural } from 'pluralize';\nimport { camelCase } from 'lodash';\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\nconst DEFAULT_SP_MAT_SELECT_ENTITY_CONFIG: SPMatSelectEntityConfig =\n {\n i18n: {\n search: 'Search',\n notFound: 'Not found',\n addItem: 'New Item',\n },\n };\n\ntype EntityGroup<T> = {\n id?: PropertyKey;\n name?: string;\n label?: string;\n description?: string;\n items?: T[];\n __items__?: T[]; // for internal use\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/**\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 <mat-select\n [placeholder]=\"placeholder\"\n (opened)=\"onSelectOpened($event)\"\n (selectionChange)=\"onSelectionChange($event)\"\n [multiple]=\"multiple\"\n [(ngModel)]=\"selectValue\"\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>\n <ngx-mat-select-search\n [(ngModel)]=\"filterStr\"\n (ngModelChange)=\"this.filter$.next($event)\"\n [placeholderLabel]=\"searchText\"\n [noEntriesFoundLabel]=\"notFoundText\"\n [searching]=\"searching\"\n >\n </ngx-mat-select-search>\n </mat-option>\n\n <ng-container *ngIf=\"!group; else groupedOptions\">\n <span *ngIf=\"filteredValues | async as entities\">\n <ng-template #defaultOptionLabelTemplate let-entity>\n {{ entityLabelFn(entity) }}\n </ng-template>\n @for (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 }\n\n <!-- <mat-option class=\"sel-entity-option\" *ngFor=\"let entity of entities\" [value]=\"entityId(entity)\">\n {{ entityLabelFn(entity) }}\n </mat-option> -->\n </span>\n </ng-container>\n <ng-template #groupedOptions>\n <span *ngIf=\"filteredGroupedValues | async as groups\">\n @for (group of groups; track groupLabel(group)) {\n <mat-optgroup [label]=\"groupLabel(group)\">\n @for (entity of group.__items__; track entityId(entity)) {\n\n <mat-option class=\"sel-entity-option\" [value]=\"entityId(entity)\">\n {{ entityLabelFn(entity) }}\n </mat-option>\n }\n </mat-optgroup>\n }\n </span>\n </ng-template>\n\n <mat-option\n *ngIf=\"!multiple && inlineNew\"\n class=\"add-item-option\"\n value=\"0\"\n (click)=\"$event.stopPropagation()\"\n >⊕ {{ addItemText }}</mat-option\n >\n </mat-select>\n `,\n styles: [\n `\n .add-item-option {\n padding-top: 2px;\n border-top: 1px solid gray;\n }\n .addl-selection-count {\n opacity: 0.75;\n font-size: 0.8em;\n }\n `,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [\n CommonModule,\n NgTemplateOutlet,\n FormsModule,\n ReactiveFormsModule,\n MatSelectModule,\n NgxMatSelectSearchModule,\n ],\n providers: [\n { provide: MatFormFieldControl, useExisting: SPMatSelectEntityComponent },\n ],\n})\nexport class SPMatSelectEntityComponent<\n TEntity extends { [P in IdKey]: PropertyKey },\n IdKey extends string = 'id'\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 endpoint.\n static _entitiesCache = new Map<\n string,\n { refCount: number; entities: Array<any> }\n >();\n\n @ViewChild(MatSelect) matSel!: MatSelect;\n\n // REQUIRED PROPERTIES //\n /**\n * Entity label function. Given an entity return its natural label\n * to display to the user.\n */\n @Input({ required: true }) entityLabelFn!: (entity: TEntity) => string;\n\n // OPTIONAL PROPERTIES //\n /**\n * Entity filter function - return a boolean if the entity is to be included\n * in the filtered entities list.\n * @param entity: TEntity object to test for 'search' string.\n * @param search - search string\n */\n @Input({ required: false }) entityFilterFn!: (\n entity: TEntity,\n search: string\n ) => boolean;\n /**\n * Entity idKey, if idKey is different from the default 'id'.\n */\n @Input({ required: false }) idKey = 'id';\n /**\n * URL of the remote from where entities are to be loaded.\n * This won't be used if `loadFromRemoteFn` is specified.\n */\n @Input({ required: false }) url!: string;\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 */\n @Input({ required: false }) httpParams!: HttpParams;\n /**\n * Function to load entities from remote.\n */\n @Input({ required: false }) loadFromRemoteFn!: (\n injector: Injector\n ) => Observable<TEntity[]>;\n\n @Input({ required: false }) inlineNew: boolean = false;\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 not an array and rather an object, 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 @Input({ required: false }) entityName!: string;\n // Set to true to allow multiple option selection. The returned value\n // would be an array of entity ids.\n @Input({ required: false }) multiple = false;\n /*\n Whether to group options using <mat-optgroup></mat-optgroup>.\n If set to true, the response from the server should be an array of\n groups of TEntity objects, where each object is of the form:\n [\n {\n id: <id>,\n name|label: <>,\n items|<plural_entityName>|<custom_key>: [\n TEntity,\n ...\n ]\n },\n ...\n ]\n */\n @Input({ required: false }) group = false;\n /**\n * The group object key name under which options are stored. Defaults to\n * 'items' or pluralized 'entityName'. Ideally the client class should\n * explicitly set this property value.\n */\n @Input({ required: false }) groupOptionsKey!: string;\n /**\n * If groupOptions = true, specify this to provide accurate label for each\n * group. If not specified, group label will be determined by looking up one\n * of the standard fields - name, label or description - whichever comes\n * first.\n */\n @Input({ required: false }) groupLabelFn!: (group: any) => string;\n /**\n * Sideload data key name.\n */\n sideloadDataKey = input<string>();\n /**\n * Parser function to return the list of entities from the GET response.\n */\n responseParserFn = input<SPMatSelectEntityResponseParser>();\n\n @Output() selectionChange = new EventEmitter<TEntity | TEntity[]>();\n @Output() createNewItemSelected = new EventEmitter<void>();\n\n // allow per component customization\n @Input() searchText!: string;\n @Input() notFoundText!: string;\n @Input() addItemText!: string;\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 * [entityLabelFn]=\"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 _sideloadDataKey = computed<string>(() => {\n if (this.sideloadDataKey()) {\n return this.sideloadDataKey() as string;\n }\n return this.entityName ? plural(camelCase(this.entityName)) : 'results';\n });\n\n private _entities = new Map<PropertyKey, TEntity>();\n private _groupedEntities = new Array<EntityGroup<TEntity>>();\n\n stateChanges = new Subject<void>();\n focused = false;\n touched = false;\n\n selectValue!: string | number | string[] | number[];\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 BehaviorSubject<string>('');\n // ControlValueAccessor callback\n onChanged = (_: any) => {};\n onTouched = () => {};\n @ViewChild(MatSelect) matSelect!: MatSelect;\n\n filteredValues = new Subject<TEntity[]>();\n filteredGroupedValues = new Subject<EntityGroup<TEntity>[]>();\n\n destroy = new Subject<void>();\n private loaded = false;\n private load$ = new BehaviorSubject<boolean>(false);\n\n static nextId = 0;\n @HostBinding() id = `sp-select-entity-${SPMatSelectEntityComponent.nextId++}`;\n private _placeholder!: string;\n ngxHelperConfig = getNgxHelperConfig();\n\n constructor(\n protected http: HttpClient,\n protected cdr: ChangeDetectorRef,\n protected _elementRef: ElementRef<HTMLElement>,\n protected injector: Injector,\n @Optional() @Inject(MAT_FORM_FIELD) public _formField: MatFormField,\n @Optional() @Self() public ngControl: NgControl,\n @Optional()\n @Inject(SP_MAT_SELECT_ENTITY_CONFIG)\n private config: SPMatSelectEntityConfig\n ) {\n if (this.ngControl != null) {\n this.ngControl.valueAccessor = this;\n }\n }\n\n ngOnInit() {\n this._initStrings();\n combineLatest([this.filter$.pipe(debounceTime(400)), this.load$])\n .pipe(\n takeUntil(this.destroy),\n switchMap(([str, load]) => {\n if (load && !this.loaded) {\n this.searching = true;\n this.cdr.detectChanges();\n return this.loadFromRemote();\n } else {\n return of(this.entities ?? []);\n }\n }),\n tap(() => {\n if (this.group) {\n this.filterGroupedValues(this.filterStr);\n } else {\n this.filterValues(this.filterStr);\n }\n this.cdr.detectChanges();\n })\n )\n .subscribe();\n }\n ngOnDestroy(): void {\n this.destroy.next();\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 }\n\n private _initStrings() {\n const config: SPMatSelectEntityConfig =\n this.config ?? DEFAULT_SP_MAT_SELECT_ENTITY_CONFIG;\n if (!this.searchText) {\n this.searchText = config.i18n.search;\n }\n if (!this.notFoundText) {\n this.notFoundText = config.i18n.notFound;\n }\n if (!this.addItemText) {\n this.addItemText = config.i18n.addItem.replace(\n /\\{\\{\\s*item\\s*}}/,\n this.entityName ?? '**Item'\n );\n }\n }\n\n addEntity(entity: TEntity) {\n this._entities.set((entity as any)[this.idKey], entity);\n // So that the newly added entity will be added to the <mat-option> list.\n this.filterValues(this.filterStr);\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._entities.get(firstSelected);\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 (Array.isArray(entityId)) {\n if (this.multiple) {\n const selectedValues: any[] = [];\n entityId.forEach((id) => {\n if (this._entities.has(id)) {\n selectedValues.push(id);\n }\n });\n this.selectValue = selectedValues;\n this.cdr.detectChanges();\n }\n } else {\n if (this._entities.has(entityId)) {\n this.selectValue = entityId;\n if (this.filterStr) {\n this.filterStr = '';\n this.filterValues(this.filterStr);\n }\n this.cdr.detectChanges();\n }\n }\n }\n registerOnChange(fn: any): void {\n this.onChanged = fn;\n }\n registerOnTouched(fn: any): void {\n this.onTouched = fn;\n }\n\n @Input()\n get entities(): TEntity[] {\n return Array.from(this._entities.values());\n }\n\n set entities(items: TEntity[]) {\n if (!this.group) {\n items.forEach((item) => {\n this._entities.set((item as any)[this.idKey], item);\n });\n } else {\n this._groupedEntities = items as any as EntityGroup<TEntity>[];\n this._groupedEntities.forEach((group) => {\n const key = this.groupEntitiesKey();\n const groupEntities = (group as any)[key] as TEntity[];\n (group as any)['__items__'] = groupEntities;\n groupEntities.forEach((item) => {\n this._entities.set((item as any)[this.idKey], item);\n });\n });\n }\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 // TODO\n return !this.value;\n }\n get errorState(): boolean {\n // TODO\n return false;\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() {\n // this._focusMonitor.focusVia(this.countrySelect, 'program');\n // if (this.parts.controls.national.valid) {\n // this._focusMonitor.focusVia(this.nationalInput, 'program');\n // } else if (this.parts.controls.country.valid) {\n // this._focusMonitor.focusVia(this.nationalInput, 'program');\n // // } else if (this.parts.controls.national.valid) {\n // // this._focusMonitor.focusVia(this.nationalInput, 'program');\n // } else {\n // this._focusMonitor.focusVia(this.countrySelect, 'program');\n // }\n }\n\n setDisabledState(isDisabled: boolean): void {\n this._disabled = isDisabled;\n if (this.matSelect) {\n this.matSelect.setDisabledState(isDisabled);\n this.cdr.detectChanges();\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.loaded) {\n this.load$.next(true); // this will trigger the loadFromRemote() call.\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._entities.get(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._entities.get(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 filterValues(search: string) {\n const searchLwr = search.toLocaleLowerCase();\n const entities = this.entities;\n if (!entities) {\n return;\n }\n if (!search) {\n this.filteredValues.next(entities.slice());\n } else {\n this.filteredValues.next(\n entities.filter((member) => {\n if (this.entityFilterFn) {\n return this.entityFilterFn(member, search);\n }\n return this.entityLabelFn(member)\n .toLocaleLowerCase()\n .includes(searchLwr);\n })\n );\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\n */\n filterGroupedValues(search: string) {\n const searchLwr = search.toLocaleLowerCase();\n const groups = this._groupedEntities;\n if (!groups) {\n return;\n }\n if (!search) {\n const groupsCopy = groups.slice();\n this.filteredGroupedValues.next(groupsCopy);\n } else {\n const groupEntitiesKey = this.groupEntitiesKey();\n const groups = this._groupedEntities.map((ge) => {\n const label = this.groupLabel(ge);\n if (label.toLocaleLowerCase().includes(searchLwr)) {\n return { ...ge } as EntityGroup<TEntity>;\n } else {\n const groupEntities = ge.__items__?.filter((e) =>\n this.entityLabelFn(e).toLocaleLowerCase().includes(searchLwr)\n );\n const ret: any = {\n ...ge,\n };\n ret['__items__'] = groupEntities ?? [];\n return ret as EntityGroup<TEntity>;\n }\n });\n // filter out groups with no entities\n // console.log(`Groups: ${JSON.stringify(groups)}`);\n this.filteredGroupedValues.next(\n groups.filter(\n (group) =>\n Array.isArray((group as any)[groupEntitiesKey]) &&\n (group as any)['__items__'].length > 0\n )\n );\n }\n }\n\n loadFromRemote() {\n if (!this.url && !this.loadFromRemoteFn) {\n // If user had initialized entities, they will be dispalyed\n // in the options list. If not, options would be empty.\n return of(this.group ? this.groupEntities : this.entities);\n }\n let cacheKey!: string;\n let obs: Observable<TEntity[]>;\n if (this.loadFromRemoteFn) {\n obs = this.loadFromRemoteFn(this.injector);\n } else {\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 cacheKey = this.getCacheKey();\n if (this.existsInCache()) {\n obs = of(this.getFromCache());\n } else {\n obs = this.http.get<any>(this.url, {\n context: this.getHttpReqContext(),\n params,\n });\n }\n }\n return obs.pipe(\n tap((entities) => {\n this.searching = false; // remote loading done, will hide the loading wheel\n // Handle DRF paginated response\n const responseParserFn = this.responseParserFn();\n if (responseParserFn) {\n entities = responseParserFn(entities) as unknown as TEntity[];\n } else {\n if (\n !Array.isArray(entities) &&\n entities['results'] &&\n Array.isArray(entities['results'])\n ) {\n entities = entities['results'];\n } else if (\n // sideloaded response, where entities are usually provided in 'entityName'\n this._sideloadDataKey() &&\n !Array.isArray(entities) &&\n typeof entities === 'object' &&\n entities[this._sideloadDataKey()] &&\n Array.isArray(entities[this._sideloadDataKey()])\n ) {\n entities = entities[this._sideloadDataKey()];\n }\n }\n if (Array.isArray(entities)) {\n this.entities = entities;\n // if (this.group) {\n // this._groupedEntities = entities as EntityGroup<TEntity>[];\n // } else {\n // this.entities = entities;\n // }\n }\n this.loaded = true;\n this.addToCache(entities);\n this.cdr.detectChanges();\n })\n );\n }\n\n groupLabel(group: EntityGroup<TEntity>): string {\n if (this.groupLabelFn) {\n return this.groupLabelFn(group);\n }\n const standardLabelFields = ['name', 'label', 'desc', 'description'];\n for (let index = 0; index < standardLabelFields.length; index++) {\n const labelField = standardLabelFields[index];\n if ((group as any)[labelField]) {\n return (group as any)[labelField];\n }\n }\n return `Group ${String(group.id)}`;\n }\n\n groupEntities(group: EntityGroup<TEntity>): TEntity[] {\n const key = this.groupEntitiesKey();\n console.log(`groupEntities - group: ${JSON.stringify(group)}, key: ${key}`);\n return (group as any)[this.groupEntitiesKey()] ?? [];\n }\n\n groupEntitiesKey() {\n return this.groupOptionsKey\n ? this.groupOptionsKey\n : this.entityName\n ? plural(this.entityName.toLocaleLowerCase())\n : 'items';\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 (!this.loadFromRemoteFn) {\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 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 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 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.entityName ? plural(this.entityName) : '',\n endpoint: this.url,\n });\n return context;\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { BooleanInput } from '@angular/cdk/coercion';
2
2
  import { HttpClient, HttpContextToken, HttpParams } from '@angular/common/http';
3
- import { AfterViewInit, ChangeDetectorRef, ElementRef, EventEmitter, Injector, OnDestroy, OnInit } from '@angular/core';
3
+ import { AfterViewInit, ChangeDetectorRef, ElementRef, EventEmitter, Injector, OnDestroy, OnInit, TemplateRef } from '@angular/core';
4
4
  import { ControlValueAccessor, NgControl } from '@angular/forms';
5
5
  import { MatFormField, MatFormFieldControl } from '@angular/material/form-field';
6
6
  import { MatSelect, MatSelectChange } from '@angular/material/select';
@@ -122,6 +122,25 @@ export declare class SPMatSelectEntityComponent<TEntity extends {
122
122
  searchText: string;
123
123
  notFoundText: string;
124
124
  addItemText: string;
125
+ /**
126
+ * Template for the option label. If not provided, the default label
127
+ * function will be used. Option label is what is placed inside the
128
+ * <mat-option> tag. The template gets an implicit 'entity' variable
129
+ * in the context, value for which is the entity object.
130
+ *
131
+ * For example:
132
+ * ```
133
+ * <sp-mat-select-entity
134
+ * [url]="'/api/v1/customers/'"
135
+ * [entityLabelFn]="entity => entity.name"
136
+ * [optionLabelTemplate]="optionLabelTemplate"
137
+ * ></sp-mat-select-entity>
138
+ * <ng-template #optionLabelTemplate let-entity>
139
+ * {{ entity.name }} - {{ entity.description }}
140
+ * </ng-template>
141
+ * ```
142
+ */
143
+ optionLabelTemplate: import("@angular/core").InputSignal<TemplateRef<any> | undefined>;
125
144
  _sideloadDataKey: import("@angular/core").Signal<string>;
126
145
  private _entities;
127
146
  private _groupedEntities;
@@ -202,6 +221,6 @@ export declare class SPMatSelectEntityComponent<TEntity extends {
202
221
  private removeFromCache;
203
222
  private getHttpReqContext;
204
223
  static ɵfac: i0.ɵɵFactoryDeclaration<SPMatSelectEntityComponent<any, any>, [null, null, null, null, { optional: true; }, { optional: true; self: true; }, { optional: true; }]>;
205
- static ɵcmp: i0.ɵɵComponentDeclaration<SPMatSelectEntityComponent<any, any>, "sp-mat-select-entity", never, { "entityLabelFn": { "alias": "entityLabelFn"; "required": true; }; "entityFilterFn": { "alias": "entityFilterFn"; "required": false; }; "idKey": { "alias": "idKey"; "required": false; }; "url": { "alias": "url"; "required": false; }; "httpParams": { "alias": "httpParams"; "required": false; }; "loadFromRemoteFn": { "alias": "loadFromRemoteFn"; "required": false; }; "inlineNew": { "alias": "inlineNew"; "required": false; }; "entityName": { "alias": "entityName"; "required": false; }; "multiple": { "alias": "multiple"; "required": false; }; "group": { "alias": "group"; "required": false; }; "groupOptionsKey": { "alias": "groupOptionsKey"; "required": false; }; "groupLabelFn": { "alias": "groupLabelFn"; "required": false; }; "sideloadDataKey": { "alias": "sideloadDataKey"; "required": false; "isSignal": true; }; "responseParserFn": { "alias": "responseParserFn"; "required": false; "isSignal": true; }; "searchText": { "alias": "searchText"; "required": false; }; "notFoundText": { "alias": "notFoundText"; "required": false; }; "addItemText": { "alias": "addItemText"; "required": false; }; "entities": { "alias": "entities"; "required": false; }; "value": { "alias": "value"; "required": false; }; "userAriaDescribedBy": { "alias": "aria-describedby"; "required": false; }; "placeholder": { "alias": "placeholder"; "required": false; }; "required": { "alias": "required"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; }, { "selectionChange": "selectionChange"; "createNewItemSelected": "createNewItemSelected"; }, never, never, true, never>;
224
+ static ɵcmp: i0.ɵɵComponentDeclaration<SPMatSelectEntityComponent<any, any>, "sp-mat-select-entity", never, { "entityLabelFn": { "alias": "entityLabelFn"; "required": true; }; "entityFilterFn": { "alias": "entityFilterFn"; "required": false; }; "idKey": { "alias": "idKey"; "required": false; }; "url": { "alias": "url"; "required": false; }; "httpParams": { "alias": "httpParams"; "required": false; }; "loadFromRemoteFn": { "alias": "loadFromRemoteFn"; "required": false; }; "inlineNew": { "alias": "inlineNew"; "required": false; }; "entityName": { "alias": "entityName"; "required": false; }; "multiple": { "alias": "multiple"; "required": false; }; "group": { "alias": "group"; "required": false; }; "groupOptionsKey": { "alias": "groupOptionsKey"; "required": false; }; "groupLabelFn": { "alias": "groupLabelFn"; "required": false; }; "sideloadDataKey": { "alias": "sideloadDataKey"; "required": false; "isSignal": true; }; "responseParserFn": { "alias": "responseParserFn"; "required": false; "isSignal": true; }; "searchText": { "alias": "searchText"; "required": false; }; "notFoundText": { "alias": "notFoundText"; "required": false; }; "addItemText": { "alias": "addItemText"; "required": false; }; "optionLabelTemplate": { "alias": "optionLabelTemplate"; "required": false; "isSignal": true; }; "entities": { "alias": "entities"; "required": false; }; "value": { "alias": "value"; "required": false; }; "userAriaDescribedBy": { "alias": "aria-describedby"; "required": false; }; "placeholder": { "alias": "placeholder"; "required": false; }; "required": { "alias": "required"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; }, { "selectionChange": "selectionChange"; "createNewItemSelected": "createNewItemSelected"; }, never, never, true, never>;
206
225
  }
207
226
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smallpearl/ngx-helper",
3
- "version": "0.29.26",
3
+ "version": "0.29.29",
4
4
  "peerDependencies": {
5
5
  "@angular/common": "^19.1.0",
6
6
  "@angular/core": "^19.1.0",
@@ -50,29 +50,29 @@
50
50
  "types": "./core/index.d.ts",
51
51
  "default": "./fesm2022/smallpearl-ngx-helper-core.mjs"
52
52
  },
53
+ "./forms": {
54
+ "types": "./forms/index.d.ts",
55
+ "default": "./fesm2022/smallpearl-ngx-helper-forms.mjs"
56
+ },
53
57
  "./entity-field": {
54
58
  "types": "./entity-field/index.d.ts",
55
59
  "default": "./fesm2022/smallpearl-ngx-helper-entity-field.mjs"
56
60
  },
57
- "./forms": {
58
- "types": "./forms/index.d.ts",
59
- "default": "./fesm2022/smallpearl-ngx-helper-forms.mjs"
61
+ "./mat-busy-wheel": {
62
+ "types": "./mat-busy-wheel/index.d.ts",
63
+ "default": "./fesm2022/smallpearl-ngx-helper-mat-busy-wheel.mjs"
60
64
  },
61
65
  "./mat-context-menu": {
62
66
  "types": "./mat-context-menu/index.d.ts",
63
67
  "default": "./fesm2022/smallpearl-ngx-helper-mat-context-menu.mjs"
64
68
  },
65
- "./locale": {
66
- "types": "./locale/index.d.ts",
67
- "default": "./fesm2022/smallpearl-ngx-helper-locale.mjs"
68
- },
69
69
  "./hover-dropdown": {
70
70
  "types": "./hover-dropdown/index.d.ts",
71
71
  "default": "./fesm2022/smallpearl-ngx-helper-hover-dropdown.mjs"
72
72
  },
73
- "./mat-busy-wheel": {
74
- "types": "./mat-busy-wheel/index.d.ts",
75
- "default": "./fesm2022/smallpearl-ngx-helper-mat-busy-wheel.mjs"
73
+ "./locale": {
74
+ "types": "./locale/index.d.ts",
75
+ "default": "./fesm2022/smallpearl-ngx-helper-locale.mjs"
76
76
  },
77
77
  "./mat-entity-crud": {
78
78
  "types": "./mat-entity-crud/index.d.ts",
@@ -98,14 +98,14 @@
98
98
  "types": "./mat-side-menu-layout/index.d.ts",
99
99
  "default": "./fesm2022/smallpearl-ngx-helper-mat-side-menu-layout.mjs"
100
100
  },
101
- "./sideload": {
102
- "types": "./sideload/index.d.ts",
103
- "default": "./fesm2022/smallpearl-ngx-helper-sideload.mjs"
104
- },
105
101
  "./mat-tel-input": {
106
102
  "types": "./mat-tel-input/index.d.ts",
107
103
  "default": "./fesm2022/smallpearl-ngx-helper-mat-tel-input.mjs"
108
104
  },
105
+ "./sideload": {
106
+ "types": "./sideload/index.d.ts",
107
+ "default": "./fesm2022/smallpearl-ngx-helper-sideload.mjs"
108
+ },
109
109
  "./stationary-with-line-items": {
110
110
  "types": "./stationary-with-line-items/index.d.ts",
111
111
  "default": "./fesm2022/smallpearl-ngx-helper-stationary-with-line-items.mjs"