2019-07-09 22:06:12 +02:00
|
|
|
import { Component, OnInit, Input, Output, EventEmitter, OnDestroy, AfterViewInit } from '@angular/core';
|
2019-07-08 11:34:14 +02:00
|
|
|
import { BehaviorSubject, Subscription } from 'rxjs';
|
2019-07-04 14:37:36 +02:00
|
|
|
import { FormGroup, FormBuilder } from '@angular/forms';
|
2019-07-08 11:34:14 +02:00
|
|
|
import { Router, NavigationEnd } from '@angular/router';
|
2019-07-04 14:37:36 +02:00
|
|
|
|
|
|
|
@Component({
|
|
|
|
selector: 'os-extension-field',
|
|
|
|
templateUrl: './extension-field.component.html',
|
|
|
|
styleUrls: ['./extension-field.component.scss']
|
|
|
|
})
|
2019-07-09 22:06:12 +02:00
|
|
|
export class ExtensionFieldComponent implements OnInit, OnDestroy, AfterViewInit {
|
2019-07-04 14:37:36 +02:00
|
|
|
/**
|
|
|
|
* 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;
|
|
|
|
|
2019-07-09 22:06:12 +02:00
|
|
|
/**
|
|
|
|
* Allow automatically jump into autoEdit
|
|
|
|
*/
|
|
|
|
private allowAutoEdit = false;
|
|
|
|
|
2019-07-04 14:37:36 +02:00
|
|
|
/**
|
|
|
|
* Boolean, whether the extension should be shown.
|
|
|
|
*/
|
2019-07-09 22:06:12 +02:00
|
|
|
private _hasExtension = false;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Setter for the extension condition
|
|
|
|
*/
|
|
|
|
@Input() public set hasExtension(extension: boolean) {
|
|
|
|
this._hasExtension = extension;
|
|
|
|
|
|
|
|
if (this.hasExtension && this.allowAutoEdit) {
|
|
|
|
this.editMode = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Getter for the extension condition
|
|
|
|
*/
|
|
|
|
public get hasExtension(): boolean {
|
|
|
|
return this._hasExtension;
|
|
|
|
}
|
2019-07-04 14:37:36 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* 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<object[]>;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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<string | object> = new EventEmitter();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* EventEmitter, if the list has changed.
|
|
|
|
*/
|
|
|
|
@Output()
|
|
|
|
public listChange: EventEmitter<number> = 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;
|
|
|
|
|
2019-07-08 11:34:14 +02:00
|
|
|
/**
|
|
|
|
* Hold the nav subscription
|
|
|
|
*/
|
|
|
|
private navigationSubscription: Subscription;
|
|
|
|
|
2019-07-09 22:06:12 +02:00
|
|
|
/**
|
|
|
|
* Subscription for the search value selector
|
|
|
|
*/
|
|
|
|
private searchValueSubscription: Subscription;
|
|
|
|
|
2019-07-04 14:37:36 +02:00
|
|
|
/**
|
|
|
|
* Constructor
|
|
|
|
*
|
|
|
|
* @param fb The FormBuilder
|
|
|
|
*/
|
2019-07-08 11:34:14 +02:00
|
|
|
public constructor(private fb: FormBuilder, private router: Router) {}
|
2019-07-04 14:37:36 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* OnInit-method.
|
|
|
|
*/
|
|
|
|
public ngOnInit(): void {
|
2019-07-08 11:34:14 +02:00
|
|
|
this.navigationSubscription = this.router.events.subscribe(navEvent => {
|
|
|
|
if (navEvent instanceof NavigationEnd) {
|
|
|
|
this.editMode = false;
|
2019-07-09 22:06:12 +02:00
|
|
|
|
|
|
|
if (this.extensionFieldForm) {
|
|
|
|
this.extensionFieldForm.reset();
|
|
|
|
}
|
2019-07-08 11:34:14 +02:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2019-07-04 14:37:36 +02:00
|
|
|
this.initInput();
|
2019-07-08 11:34:14 +02:00
|
|
|
|
2019-07-09 22:06:12 +02:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
2019-07-04 14:37:36 +02:00
|
|
|
|
2019-07-09 22:06:12 +02:00
|
|
|
/**
|
|
|
|
* After view inits, allow to automatically open the edit view
|
|
|
|
*/
|
|
|
|
public ngAfterViewInit(): void {
|
|
|
|
this.allowAutoEdit = true;
|
2019-07-04 14:37:36 +02:00
|
|
|
}
|
|
|
|
|
2019-07-08 11:34:14 +02:00
|
|
|
/**
|
2019-07-09 22:06:12 +02:00
|
|
|
* On destroy unsubscribe from the subscriptions
|
2019-07-08 11:34:14 +02:00
|
|
|
*/
|
|
|
|
public ngOnDestroy(): void {
|
|
|
|
this.navigationSubscription.unsubscribe();
|
2019-07-09 22:06:12 +02:00
|
|
|
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);
|
|
|
|
}
|
2019-07-08 11:34:14 +02:00
|
|
|
}
|
|
|
|
|
2019-07-04 14:37:36 +02:00
|
|
|
/**
|
|
|
|
* 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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|