import { Component, Inject } from '@angular/core'; import { FormArray, FormBuilder, FormControl, FormGroup } from '@angular/forms'; import { MatAutocompleteSelectedEvent } from '@angular/material/autocomplete'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { round } from 'mathjs'; import { Observable, of as observableOf } from 'rxjs'; import { debounceTime, distinctUntilChanged, map, startWith, switchMap } from 'rxjs/operators'; import { Customer } from '../../core/customer'; import { CustomerService } from '../../customers/customer.service'; @Component({ selector: 'app-choose-customer', templateUrl: './choose-customer.component.html', styleUrls: ['./choose-customer.component.css'], }) export class ChooseCustomerComponent { form: FormGroup; item: Customer = new Customer(); customers: Observable; constructor( public dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) public data: string | undefined, private fb: FormBuilder, private ser: CustomerService, ) { // Create form this.form = this.fb.group({ name: '', phone: '', address: '', printInBill: false, discounts: this.fb.array([]), }); // Setup Account Autocomplete this.customers = (this.form.get('phone') as FormControl).valueChanges.pipe( startWith(null), map((x) => (x === this.item.phone ? '' : x)), map((x) => (x !== null && x.length >= 1 ? x : null)), debounceTime(150), distinctUntilChanged(), switchMap((x) => (x === null ? observableOf([]) : this.ser.autocomplete(x))), ); if (data) { this.ser.get(data).subscribe((x) => this.showItem(x)); } } showItem(item: Customer) { this.item = item; this.form.patchValue({ name: item.name, phone: item.phone, address: item.address, printInBill: item.printInBill, }); this.form.setControl( 'discounts', this.fb.array( item.discounts.map((x) => this.fb.group({ discount: '' + x.discount * 100, }), ), ), ); this.form.markAsPristine(); } save() { const customer = this.getItem(); const promise = this.form.pristine ? observableOf(customer) : this.ser.saveOrUpdate(customer); promise.subscribe((x) => this.dialogRef.close(x)); } displayFn(customer?: Customer | string): string { if (!customer) { return ''; } return typeof customer === 'string' ? customer : customer.phone; } selected(event: MatAutocompleteSelectedEvent): void { const customer: Customer = event.option.value; this.showItem(customer); } getItem(): Customer { const formModel = this.form.value; this.item.id = this.item.phone.trim() !== formModel.phone.trim() ? '' : this.item.id; this.item.name = formModel.name; this.item.phone = formModel.phone; this.item.address = formModel.address; this.item.printInBill = formModel.printInBill; const array = this.form.get('discounts') as FormArray; this.item.discounts.forEach((item, index) => { item.discount = Math.max( Math.min(round(array.controls[index].value.discount / 100, 5), 100), 0, ); }); return this.item; } }