111 lines
3.4 KiB
TypeScript
111 lines
3.4 KiB
TypeScript
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<Customer | null>(MAT_DIALOG_DATA); // Customer ID
|
|
private ser = inject(CustomerService);
|
|
dialogRef = inject<MatDialogRef<ChooseCustomerComponent>>(MatDialogRef);
|
|
|
|
item = signal<Customer>(this.data ?? new Customer());
|
|
|
|
formModel = linkedSignal<Customer, ChooseCustomerFormData>({
|
|
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<Customer[] | undefined, Customer[]>({
|
|
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 })),
|
|
});
|
|
}
|
|
}
|