import { CdkScrollableModule } from '@angular/cdk/scrolling'; import { PercentPipe } from '@angular/common'; import { Component, inject, computed, debounced, linkedSignal, signal } from '@angular/core'; import { form, FormField } from '@angular/forms/signals'; import { MatAutocompleteSelectedEvent, MatAutocompleteModule } from '@angular/material/autocomplete'; import { MatButtonModule } from '@angular/material/button'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatOptionModule } from '@angular/material/core'; import { MAT_DIALOG_DATA, MatDialogRef, MatDialogModule } from '@angular/material/dialog'; import { MatFormFieldModule } from '@angular/material/form-field'; import { MatInputModule } from '@angular/material/input'; import { Customer } from '../../core/customer'; import { CustomerDiscount } from '../../core/customer-discount'; import { CustomerService } from '../../customers/customer.service'; export interface ChooseCustomerFormData { id: string; name: string; phone: string; address: string; printInBill: boolean; discounts: CustomerDiscount[]; } @Component({ selector: 'app-choose-customer', templateUrl: './choose-customer.component.html', styleUrls: ['./choose-customer.component.css'], imports: [ CdkScrollableModule, MatAutocompleteModule, MatButtonModule, MatCheckboxModule, MatDialogModule, MatFormFieldModule, MatInputModule, MatOptionModule, PercentPipe, FormField, ], }) export class ChooseCustomerComponent { data = inject(MAT_DIALOG_DATA); // Customer ID private ser = inject(CustomerService); dialogRef = inject>(MatDialogRef); item = signal(this.data ?? new Customer()); formModel = linkedSignal({ source: () => this.item(), computation: (data) => ({ id: data.id, name: data.name, phone: data.phone, address: data.address ?? '', printInBill: data.printInBill, discounts: data.discounts ?? [], }), }); form = form(this.formModel); phoneSignal = computed(() => { const p = this.formModel().phone; return typeof p === 'string' ? p.trim() : null; }); debouncedPhone = debounced(this.phoneSignal, 300); customersResource = this.ser.autocomplete(this.debouncedPhone.value); customers = linkedSignal({ source: () => this.customersResource.value(), computation: (newVal, previous) => { if (!this.debouncedPhone.value()) return []; return newVal ?? previous?.value ?? []; }, }); save() { const customer = this.getItem(); const promise = 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.item.set(customer); } getItem(): Customer { const formModel = this.formModel(); return new Customer({ id: formModel.id, name: formModel.name ?? '', phone: formModel.phone ?? '', address: formModel.address ?? '', printInBill: formModel.printInBill ?? false, discounts: formModel.discounts.map((item) => ({ ...item })), }); } }