Files
barker/bookie/src/app/sales/choose-customer/choose-customer.component.ts
T

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 })),
});
}
}