import { DatePipe, NgFor, NgIf } from '@angular/common'; import { Component, EventEmitter, OnInit } from '@angular/core'; import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms'; import { ActivatedRoute, Router, RouterLink } from '@angular/router'; import { isEqual } from 'lodash'; import { BehaviorSubject, finalize, map } from 'rxjs'; import { RecipeService } from 'src/app/core/services/recipe.service'; import { ConfirmModal } from 'src/app/shared/modal/confirm/confirm-modal.component'; import { animate, style, transition, trigger } from '@angular/animations'; import { MaterialService } from 'src/app/core/services/material.service'; import { RecipeMetaData, RecipeDetail } from 'src/app/shared/types/recipe'; import { RecipeListComponent } from './recipe-list/recipe-list.component'; @Component({ selector: 'app-recipe-details', templateUrl: './recipe-details.component.html', standalone: true, imports: [ NgIf, NgFor, RouterLink, ReactiveFormsModule, ConfirmModal, DatePipe, RecipeListComponent, ], animations: [ trigger('inOutAnimation', [ transition(':enter', [ style({ opacity: 0 }), animate('1s ease-out', style({ opacity: 1 })), ]), ]), ], }) export class RecipeDetailsComponent implements OnInit { title: string = 'Recipe Detail'; recipeMetaData: RecipeMetaData | null = null; originalRecipeDetail: BehaviorSubject = new BehaviorSubject(null); matForRecipeList = this.originalRecipeDetail.pipe( map((x) => x?.recipe.recipes) ); isLoaded: boolean = false; isMatLoaded: boolean = false; constructor( private _route: ActivatedRoute, private _router: Router, private _recipeService: RecipeService, private _materialService: MaterialService ) {} recipeDetail = new FormGroup({ productCode: new FormControl(''), name: new FormControl(''), otherName: new FormControl(''), description: new FormControl(''), otherDescription: new FormControl(''), price: new FormControl(0), isUse: new FormControl(false), isShow: new FormControl(false), disable: new FormControl(false), }); ngOnInit() { this._recipeService .getRecipesById(this._route.snapshot.params['productCode']) .pipe(finalize(() => {})) .subscribe(({ recipe, recipeMetaData }) => { this.title = recipe.name + ' | ' + recipe.productCode; this.recipeDetail.patchValue({ productCode: recipe.productCode, name: recipe.name, otherName: recipe.otherName, description: recipe.Description, otherDescription: recipe.otherDescription, price: recipe.cashPrice, isUse: recipe.isUse, isShow: recipe.isShow, disable: recipe.disable, }); this.originalRecipeDetail.next({ recipe: { lastModified: recipe.LastChange, productCode: recipe.productCode, name: recipe.name, otherName: recipe.otherName, description: recipe.Description, otherDescription: recipe.otherDescription, price: recipe.cashPrice, isUse: recipe.isUse, isShow: recipe.isShow, disable: recipe.disable, }, recipes: recipe.recipes, }); this.recipeMetaData = recipeMetaData; this.isLoaded = true; }); this.originalRecipeDetail.subscribe((originalRecipeDetail) => { if (originalRecipeDetail == null) return; const ids = originalRecipeDetail.recipes?.map( (recipe) => recipe.materialPathId ); this._materialService.getMaterialCodes(ids).subscribe((data) => { this.originalRecipeDetail.next({ ...originalRecipeDetail, recipe: { ...originalRecipeDetail.recipe, recipes: originalRecipeDetail .recipes!.map((item) => { for (let i = 0; i < data.length; i++) { if (item.materialPathId === 0) { return { id: 0, name: '', enable: item.isUse, mixOrder: item.MixOrder, stirTime: item.stirTime, powderGram: item.powderGram, powderTime: item.powderTime, syrupGram: item.syrupGram, syrupTime: item.syrupTime, waterCold: item.waterCold, waterHot: item.waterYield, }; } if (item.materialPathId === data[i].materialID) { return { id: data[i].materialID, name: data[i].PackageDescription, enable: item.isUse, mixOrder: item.MixOrder, stirTime: item.stirTime, powderGram: item.powderGram, powderTime: item.powderTime, syrupGram: item.syrupGram, syrupTime: item.syrupTime, waterCold: item.waterCold, waterHot: item.waterYield, }; } } return { id: item.materialPathId, name: '', enable: item.isUse, mixOrder: item.MixOrder, stirTime: item.stirTime, powderGram: item.powderGram, powderTime: item.powderTime, syrupGram: item.syrupGram, syrupTime: item.syrupTime, waterCold: item.waterCold, waterHot: item.waterYield, }; }) .sort((a, b) => { return a.id === 0 ? 1 : a.id > b.id ? 1 : -1; }), }, }); this.isMatLoaded = true; }); }); } showConfirmSaveModal: EventEmitter = new EventEmitter(); showConfirmCloseModal: EventEmitter = new EventEmitter(); confirmSave = { title: 'The changes detected!', message: 'Do you want to save changes?', confirmCallBack: () => { console.log('confirm save'); this._router.navigate(['/recipes']); }, }; confirmClose = { title: 'The changes will be lost!', message: 'Do you want to close without saving?', confirmCallBack: () => { console.log('confirm close'); this._router.navigate(['/recipes']); }, }; onPressConfirmSave() { if (this.isValueChanged) { this.showConfirmSaveModal.emit(true); } else { this._router.navigate(['/recipes']); } } onPressConfirmClose() { if (this.isValueChanged) { this.showConfirmCloseModal.emit(true); } else { this._router.navigate(['/recipes']); } } get isValueChanged() { return !isEqual( this.recipeDetail.value, this.originalRecipeDetail.getValue()?.recipe ); } }