Warning, /firebird/firebird-ng/src/app/components/resource-select/resource-select.component.ts is written in an unsupported language. File is not indexed.
0001 import { Component, EventEmitter, Input, OnInit, Output } 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 styleUrl: './resource-select.component.scss'
0027 })
0028 export class ResourceSelectComponent implements OnInit {
0029
0030 /**
0031 * List of resources to display in autocomplete
0032 */
0033 @Input() options: string[] = [];
0034
0035 /**
0036 * Watermark text of the control
0037 */
0038 @Input() label: string = 'Select value';
0039
0040 /**
0041 * Emitted every time value is changed by selecting or typing in
0042 */
0043 @Output() valueChange = new EventEmitter<string>();
0044
0045 /**
0046 * The main and resulting value of the control
0047 */
0048 public value: FormControl = new FormControl();
0049
0050 /**
0051 * List of filtered options depending on user input
0052 */
0053 public filteredOptions: Observable<string[]> = this.value.valueChanges.pipe(
0054 startWith(''),
0055 map(input=>this.filterOptions(input))
0056 );
0057
0058 ngOnInit(): void {
0059 // Connect value changes with the control output
0060 this.value.valueChanges.subscribe(()=>{
0061 this.valueChange.emit(this.value.value)
0062 });
0063 }
0064
0065 /**
0066 * Filters options depending on what is the value
0067 * @param inputValue
0068 * @private
0069 */
0070 private filterOptions(inputValue: any) {
0071
0072 // options could be undefined
0073 if(!this.options) return [];
0074
0075 // Safeguard the name. inputValue could be string or RemoteResourceOption or whatever...
0076 const name = typeof inputValue === 'string' ? inputValue : (inputValue?.name ?? '');
0077
0078 // Get options containing "name"
0079 let filteredList = name ? this._selectOptions(name) : this.options.slice();
0080
0081 // Explanation of the return: if we have only 1 option, that fully fit the name,
0082 // we probably have it selected already. Which means we want to show everything, so users can select something else
0083 return (filteredList.length == 1 && name === filteredList[0]) ? this.options.slice() : filteredList;
0084 }
0085
0086 /**
0087 * Retrieves the options which .name contains subString.
0088 *
0089 * @param {string} subString - sub string that every option.name is tested by.
0090 * @return {string[]} The filtered remote resource options.
0091 */
0092 private _selectOptions(subString: string): string[] {
0093 const filterValue = subString.toLowerCase();
0094 return this.options.filter(option => option.toLowerCase().includes(filterValue));
0095 }
0096
0097 /**
0098 * Display proper value if value is selected or typed in by user
0099 *
0100 * @param {any | string} input - It is a string (if user is typing) or RemoteResourceOption (if it is selected)
0101 * @return {string} We should return some string instead
0102 */
0103 onDisplayValueChange(input: any | string): string {
0104 let result: string = '';
0105 if (typeof input === 'string') {
0106 result = input;
0107 } else if (input && typeof input.url === 'string') {
0108 result = input.url;
0109 }
0110 return result;
0111 }
0112 }