import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core'; import { FormBuilder, FormGroup } from '@angular/forms'; import { NavigationEnd, Router } from '@angular/router'; import { BehaviorSubject, Subscription } from 'rxjs'; @Component({ selector: 'os-extension-field', templateUrl: './extension-field.component.html', styleUrls: ['./extension-field.component.scss'] }) export class ExtensionFieldComponent implements OnInit, OnDestroy { /** * Optional additional classes for the `mat-chip`. */ @Input() public classes: string | string[] | object = 'bluegrey'; /** * Title for this component. */ @Input() public title: string; /** * Value of the chip. */ @Input() public chipValue: string; /** * Boolean, whether the extension should be shown. */ @Input() public hasExtension = false; /** * Optional label for the input. */ @Input() public extensionLabel: string; /** * Optional label for the search-list. */ @Input() public searchListLabel: string; /** * BehaviourSubject for the search-list. */ @Input() public searchList: BehaviorSubject; /** * Boolean, whether the input and the search-list can be changed. */ @Input() public canBeEdited = true; /** * Boolean, whether the list should fire events, if it changes. */ @Input() public listSubmitOnChange = false; /** * Boolean, whether to append the value from list to the input. */ @Input() public appendValueToInput = true; /** * Prefix, if the value from list should be appended to the input. */ @Input() public listValuePrefix = ''; /** * Suffix, if the value from list should be appended to the input. */ @Input() public listValueSuffix = ''; /** * Initial value of the input-field. */ @Input() public inputValue: string; /** * EventEmitter, when clicking on the 'save'-button. */ @Output() public success: EventEmitter = new EventEmitter(); /** * EventEmitter, if the list has changed. */ @Output() public listChange: EventEmitter = new EventEmitter(); /** * Model for the input-field. */ public inputControl = ''; /** * FormGroup for the search-list. */ public extensionFieldForm: FormGroup; /** * Boolean to decide, whether to open the extension-input and search-list. */ public editMode = false; /** * Hold the nav subscription */ private navigationSubscription: Subscription; /** * Subscription for the search value selector */ private searchValueSubscription: Subscription; /** * Constructor * * @param fb The FormBuilder */ public constructor(private fb: FormBuilder, private router: Router) {} /** * OnInit-method. */ public ngOnInit(): void { this.navigationSubscription = this.router.events.subscribe(navEvent => { if (navEvent instanceof NavigationEnd) { this.editMode = false; if (this.extensionFieldForm) { this.extensionFieldForm.reset(); } } }); this.initInput(); if (this.searchList) { this.extensionFieldForm = this.fb.group({ list: [[]] }); this.searchValueSubscription = this.extensionFieldForm .get('list') .valueChanges.subscribe((value: number) => { if (!!value) { if (this.listSubmitOnChange) { this.listChange.emit(value); } if (this.appendValueToInput) { if (!this.inputControl) { this.inputControl = ''; } this.inputControl += `[${this.listValuePrefix}${value}${this.listValueSuffix}]`; } this.extensionFieldForm.reset(); } }); } } /** * On destroy unsubscribe from the subscriptions */ public ngOnDestroy(): void { this.navigationSubscription.unsubscribe(); if (this.searchValueSubscription) { this.searchValueSubscription.unsubscribe(); } } /** * Hitting enter on the input field should save the content */ public keyDownFunction(event: any): void { if (event.key === 'Enter') { this.changeEditMode(true); } } /** * Function to switch to or from editing-mode. * * @param save Boolean, whether the changes should be saved or resetted. */ public changeEditMode(save: boolean = false): void { if (save) { this.sendSuccess(); } else { this.initInput(); } this.editMode = !this.editMode; } /** * Initialize the value of the input. */ public initInput(): void { this.inputControl = this.inputValue; } /** * Function to execute, when the values are saved. */ public sendSuccess(): void { if (this.success) { const submitMessage = this.listSubmitOnChange || this.appendValueToInput || !this.searchList ? this.inputControl : { extensionInput: this.inputControl, extensionList: this.extensionFieldForm.get('list').value }; this.success.emit(submitMessage); } } }