All files / select/select-list si-select-list-has-filter.component.ts

89.28% Statements 25/28
77.77% Branches 7/9
88.88% Functions 8/9
88% Lines 22/25

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99                                                                                              1x   13x   13x   13x   13x 13x     13x 13x     13x 13x 11x 24x     2x         13x 13x 13x       22x       6x 3x         3x     3x   6x      
/**
 * Copyright (c) Siemens 2016 - 2025
 * SPDX-License-Identifier: MIT
 */
import { NgTemplateOutlet } from '@angular/common';
import {
  ChangeDetectionStrategy,
  Component,
  computed,
  ElementRef,
  input,
  OnInit,
  Signal,
  signal,
  viewChild
} from '@angular/core';
import { SiAutocompleteDirective, SiAutocompleteModule } from '@siemens/element-ng/autocomplete';
import { addIcons, elementSearch, SiIconComponent } from '@siemens/element-ng/icon';
import { SiLoadingSpinnerComponent } from '@siemens/element-ng/loading-spinner';
import { SiTranslatePipe, TranslatableString } from '@siemens/element-translate-ng/translate';
 
import { SiSelectOptionRowComponent } from '../select-option/si-select-option-row.component';
import { SiSelectGroupTemplateDirective } from '../si-select-group-template.directive';
import { SiSelectOptionRowTemplateDirective } from '../si-select-option-row-template.directive';
import { SiSelectListBase } from './si-select-list.base';
 
@Component({
  selector: 'si-select-list-has-filter',
  imports: [
    NgTemplateOutlet,
    SiAutocompleteDirective,
    SiIconComponent,
    SiSelectGroupTemplateDirective,
    SiSelectOptionRowComponent,
    SiSelectOptionRowTemplateDirective,
    SiTranslatePipe,
    SiAutocompleteModule,
    SiLoadingSpinnerComponent
  ],
  templateUrl: './si-select-list-has-filter.component.html',
  styleUrl: './si-select-list-has-filter.component.scss',
  changeDetection: ChangeDetectionStrategy.OnPush,
  host: {
    class: 'pt-0',
    '[attr.id]': 'id()'
  }
})
export class SiSelectListHasFilterComponent<T> extends SiSelectListBase<T> implements OnInit {
  /** Placeholder for search input field. */
  readonly filterPlaceholder = input.required<TranslatableString>();
  /** Label if no item can be found. */
  readonly noResultsFoundLabel = input.required<TranslatableString>();
 
  protected readonly filterInput = viewChild.required<ElementRef<HTMLInputElement>>('filter');
  protected readonly initIndex: Signal<number>;
  protected readonly id = computed(() => `${this.baseId()}-listbox`);
  protected readonly icons = addIcons({ elementSearch });
 
  constructor() {
    super();
    Iif (!this.selectOptions.onFilter) {
      console.error('Missing implementation for `onFilter`');
    }
    const firstValue = this.selectionStrategy.arrayValue()[0];
    if (firstValue) {
      this.initIndex = computed(() =>
        this.rows().findIndex(row => row.type === 'option' && row.value === firstValue)
      );
    } else {
      this.initIndex = signal(0);
    }
  }
 
  override ngOnInit(): void {
    super.ngOnInit();
    this.selectOptions.onFilter!();
    setTimeout(() => this.filterInput().nativeElement.focus());
  }
 
  protected input(): void {
    this.selectOptions.onFilter!(this.filterInput().nativeElement.value);
  }
 
  protected select(newValue: T): void {
    if (this.selectionStrategy.allowMultiple) {
      Iif (this.selectionStrategy.arrayValue().includes(newValue)) {
        this.selectionStrategy.updateFromUser(
          this.selectionStrategy.arrayValue().filter(value => value !== newValue)
        );
      } else {
        this.selectionStrategy.updateFromUser([...this.selectionStrategy.arrayValue(), newValue]);
      }
    } else {
      this.selectionStrategy.updateFromUser([newValue]);
    }
    this.closeOverlayIfSingle();
  }
}