import { Component, computed, inject, linkedSignal, input, afterNextRender } from '@angular/core'; import { form, FormField, required } from '@angular/forms/signals'; import { MatButtonModule } from '@angular/material/button'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatOptionModule } from '@angular/material/core'; import { MatDialog } from '@angular/material/dialog'; import { MatFormFieldModule } from '@angular/material/form-field'; import { MatInputModule } from '@angular/material/input'; import { MatSelectModule } from '@angular/material/select'; import { MatSnackBar } from '@angular/material/snack-bar'; import { Router } from '@angular/router'; import { Modifier } from '../../core/modifier'; import { ModifierCategory } from '../../core/modifier-category'; import { ModifierCategoryService } from '../../modifier-categories/modifier-category.service'; import { ConfirmDialogComponent } from '../../shared/confirm-dialog/confirm-dialog.component'; import { ErrorStateComponent } from '../../shared/error-state/error-state.component'; import { SkeletonLoaderComponent } from '../../shared/skeleton-loader/skeleton-loader.component'; import { ModifierService } from '../modifier.service'; export interface ModifierDetailFormData { name: string; showInBill: boolean; price: number; modifierCategory: string; isActive: boolean; } @Component({ selector: 'app-modifier-detail', templateUrl: './modifier-detail.component.html', styleUrls: ['./modifier-detail.component.css'], imports: [ MatButtonModule, MatCheckboxModule, MatFormFieldModule, MatInputModule, MatOptionModule, MatSelectModule, FormField, ErrorStateComponent, SkeletonLoaderComponent, ], }) export class ModifierDetailComponent { private modifierCategoryService = inject(ModifierCategoryService); private router = inject(Router); private dialog = inject(MatDialog); private snackBar = inject(MatSnackBar); private ser = inject(ModifierService); id = input(null, { transform: (v: string | null | undefined) => v ?? null }); modifierCategoriesResource = this.modifierCategoryService.list(); modifierCategories = computed(() => this.modifierCategoriesResource.value() ?? []); itemResource = this.ser.get(this.id); item = computed(() => this.itemResource.value() ?? new Modifier()); formModel = linkedSignal({ source: this.item, computation: (itemVal): ModifierDetailFormData => { return { name: itemVal.name ?? '', showInBill: itemVal.showInBill, price: itemVal.price ?? 0, isActive: itemVal.isActive, modifierCategory: itemVal.modifierCategory ? (itemVal.modifierCategory.id as string) : '', }; }, }); form = form(this.formModel, (schema) => { required(schema.modifierCategory, { message: 'Modifier Category is required' }); }); constructor() { afterNextRender(() => { this.form().focusBoundControl(); }); } save() { this.ser.saveOrUpdate(this.getItem()).subscribe({ next: () => { this.snackBar.open('', 'Success'); this.router.navigateByUrl('/modifiers'); }, error: (error: unknown) => { this.snackBar.open(error as string, 'Error'); }, }); } delete() { this.ser.delete(this.item().id as string).subscribe({ next: () => { this.snackBar.open('', 'Success'); this.router.navigateByUrl('/modifiers'); }, error: (error: unknown) => { this.snackBar.open(error as string, 'Error'); }, }); } confirmDelete(): void { const dialogRef = this.dialog.open(ConfirmDialogComponent, { width: '250px', data: { title: 'Delete Modifier?', content: 'Are you sure? This cannot be undone.' }, }); dialogRef.afterClosed().subscribe((result: boolean) => { if (result) { this.delete(); } }); } getItem(): Modifier { const formModel = this.formModel(); return new Modifier({ ...this.item(), name: formModel.name ?? '', showInBill: formModel.showInBill ?? false, price: formModel.price ?? 0, isActive: formModel.isActive ?? true, modifierCategory: new ModifierCategory({ id: formModel.modifierCategory }), }); } }