import { CdkScrollableModule } from '@angular/cdk/scrolling'; import { PercentPipe } from '@angular/common'; import { Component, inject } from '@angular/core'; import { FormArray, FormControl, FormGroup, Validators, ReactiveFormsModule } from '@angular/forms'; import { MatButtonModule } from '@angular/material/button'; import { MAT_DIALOG_DATA, MatDialogRef, MatDialogModule } from '@angular/material/dialog'; import { MatFormFieldModule } from '@angular/material/form-field'; import { MatInputModule } from '@angular/material/input'; import { MatTableModule } from '@angular/material/table'; import { round } from 'mathjs'; import { BehaviorSubject, Observable } from 'rxjs'; import { DiscountDataSource } from './discount-datasource'; import { DiscountItem } from './discount-item'; @Component({ selector: 'app-modifiers', templateUrl: './discount.component.html', styleUrls: ['./discount.component.css'], imports: [ CdkScrollableModule, MatButtonModule, MatDialogModule, MatFormFieldModule, MatInputModule, MatTableModule, PercentPipe, ReactiveFormsModule, ], }) export class DiscountComponent { dialogRef = inject>(MatDialogRef); data = inject>(MAT_DIALOG_DATA); list: DiscountItem[] = []; form: FormGroup<{ discounts: FormArray< FormGroup<{ name: FormControl; discount: FormControl; }> >; }>; public listObservable = new BehaviorSubject([]); dataSource: DiscountDataSource = new DiscountDataSource(this.listObservable); displayedColumns = ['name', 'discount']; constructor() { this.form = new FormGroup({ discounts: new FormArray< FormGroup<{ name: FormControl; discount: FormControl; }> >([]), }); this.data.subscribe((list: DiscountItem[]) => { this.list = list; this.form.controls.discounts.clear(); this.list.forEach((x) => { this.form.controls.discounts.push( new FormGroup({ name: new FormControl(x.name, { nonNullable: true }), discount: new FormControl(x.discount * 100, { validators: [Validators.min(0), Validators.max(x.limit * 100)], nonNullable: true, }), }), ); }); this.listObservable.next(this.list); }); } accept(): void { const array = this.form.controls.discounts; for (let i = this.list.length - 1; i >= 0; i--) { const item = this.list[i]; const control = array.controls[i].controls.discount; if (control.pristine && control.value === 0) { this.list.splice(i, 1); } else { item.discount = Math.max(Math.min(round(control.value / 100, 5), item.limit), 0); } } this.dialogRef.close(this.list); } }