Warning, /firebird/packages/firebird-ng/display/src/lib/components/resource-select/resource-select.component.ts is written in an unsupported language. File is not indexed.
0001 import { Component, EventEmitter, Input, OnInit, Output, ChangeDetectionStrategy } from '@angular/core';
0002 import {FormControl, ReactiveFormsModule} from '@angular/forms';
0003 import { Observable } from 'rxjs';
0004 import { map, startWith } from 'rxjs/operators';
0005 import {MatFormField} from "@angular/material/form-field";
0006 import {MatAutocomplete, MatAutocompleteTrigger, MatOption} from "@angular/material/autocomplete";
0007 import {AsyncPipe, NgForOf} from "@angular/common";
0008 import {MatTooltip} from "@angular/material/tooltip";
0009 import {MatInput, MatLabel} from "@angular/material/input";
0010
0011
0012 @Component({
0013 selector: 'firebird-resource-select',
0014 imports: [
0015 MatFormField,
0016 MatAutocompleteTrigger,
0017 MatAutocomplete,
0018 MatOption,
0019 AsyncPipe,
0020 NgForOf,
0021 MatInput,
0022 MatLabel,
0023 ReactiveFormsModule
0024 ],
0025 templateUrl: './resource-select.component.html',
0026 changeDetection: ChangeDetectionStrategy.OnPush,
0027 styleUrl: './resource-select.component.scss'
0028 })
0029 export class ResourceSelectComponent implements OnInit {
0030
0031 /**
0032 * List of resources to display in autocomplete
0033 */
0034 @Input() options: string[] = [];
0035
0036 /**
0037 * Watermark text of the control
0038 */
0039 @Input() label: string = 'Select value';
0040
0041 /**
0042 * Sets the shown value without emitting `valueChange` — for a host that
0043 * seeds the control from its own state and listens for user edits only
0044 */
0045 @Input() set selected(value: string | null | undefined) {
0046 this.value.setValue(value ?? '', { emitEvent: false });
0047 }
0048
0049 /**
0050 * Emitted every time value is changed by selecting or typing in
0051 */
0052 @Output() valueChange = new EventEmitter<string>();
0053
0054 /**
0055 * The main and resulting value of the control
0056 */
0057 public value: FormControl = new FormControl();
0058
0059 /**
0060 * List of filtered options depending on user input
0061 */
0062 public filteredOptions: Observable<string[]> = this.value.valueChanges.pipe(
0063 startWith(''),
0064 map(input=>this.filterOptions(input))
0065 );
0066
0067 ngOnInit(): void {
0068 // Connect value changes with the control output
0069 this.value.valueChanges.subscribe(()=>{
0070 this.valueChange.emit(this.value.value)
0071 });
0072 }
0073
0074 /**
0075 * Filters options depending on what is the value
0076 * @param inputValue
0077 * @private
0078 */
0079 private filterOptions(inputValue: any) {
0080
0081 // options could be undefined
0082 if(!this.options) return [];
0083
0084 // Safeguard the name. inputValue could be string or RemoteResourceOption or whatever...
0085 const name = typeof inputValue === 'string' ? inputValue : (inputValue?.name ?? '');
0086
0087 // Get options containing "name"
0088 let filteredList = name ? this._selectOptions(name) : this.options.slice();
0089
0090 // Explanation of the return: if we have only 1 option, that fully fit the name,
0091 // we probably have it selected already. Which means we want to show everything, so users can select something else
0092 return (filteredList.length == 1 && name === filteredList[0]) ? this.options.slice() : filteredList;
0093 }
0094
0095 /**
0096 * Retrieves the options which .name contains subString.
0097 *
0098 * @param {string} subString - sub string that every option.name is tested by.
0099 * @return {string[]} The filtered remote resource options.
0100 */
0101 private _selectOptions(subString: string): string[] {
0102 const filterValue = subString.toLowerCase();
0103 return this.options.filter(option => option.toLowerCase().includes(filterValue));
0104 }
0105
0106 /**
0107 * Display proper value if value is selected or typed in by user
0108 *
0109 * @param {any | string} input - It is a string (if user is typing) or RemoteResourceOption (if it is selected)
0110 * @return {string} We should return some string instead
0111 */
0112 onDisplayValueChange(input: any | string): string {
0113 let result: string = '';
0114 if (typeof input === 'string') {
0115 result = input;
0116 } else if (input && typeof input.url === 'string') {
0117 result = input.url;
0118 }
0119 return result;
0120 }
0121 }