fix(image):

This commit is contained in:
pakintada@gmail.com 2024-06-03 10:12:16 +07:00
parent 2b8745679f
commit 040c3c7751
6 changed files with 459 additions and 437 deletions

View file

@ -1,372 +1,376 @@
import { CommonModule, DatePipe } from '@angular/common';
import { Component, EventEmitter, OnInit } from '@angular/core';
import { FormBuilder, FormsModule, ReactiveFormsModule } from '@angular/forms';
import { ActivatedRoute, Router, RouterLink } from '@angular/router';
import { Observable, first, 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 { RecipeListComponent } from './recipe-list/recipe-list.component';
import {
Recipe01,
RecipeDetail,
RecipeDetailMat,
Topping,
ToppingSet,
} from 'src/app/core/models/recipe.model';
import { ActionRecord } from 'src/app/shared/actionRecord/actionRecord';
import { UserService } from 'src/app/core/services/user.service';
import { UserPermissions } from 'src/app/core/auth/userPermissions';
import { ToppingService } from 'src/app/core/services/topping.service';
import { copy, transformToTSV } from 'src/app/shared/helpers/copy';
import { isEqual } from 'lodash';
import { environment } from 'src/environments/environment';
@Component({
selector: 'app-recipe-details',
templateUrl: './recipe-details.component.html',
standalone: true,
animations: [
trigger('inOutAnimation', [
transition(':enter', [
style({ opacity: 0 }),
animate('1s ease-out', style({ opacity: 1 })),
]),
]),
],
imports: [
CommonModule,
RouterLink,
ReactiveFormsModule,
ConfirmModal,
DatePipe,
RecipeListComponent,
FormsModule,
],
})
export class RecipeDetailsComponent implements OnInit {
title: string = 'Recipe Detail';
recipeDetail$!: Observable<RecipeDetail>;
isLoaded: boolean = false;
isMatLoaded: boolean = false;
actionRecord: ActionRecord<RecipeDetail | RecipeDetailMat> =
new ActionRecord();
recipeOriginalDetail!: typeof this.recipeDetailForm.value;
commit_msg: string = '';
//
department: string = this._route.parent!.snapshot.params['department'];
constructor(
private _formBuilder: FormBuilder,
private _route: ActivatedRoute,
private _router: Router,
private _recipeService: RecipeService,
private _toppingService: ToppingService,
private _userService: UserService
) {}
productCode!: any;
changedProductCode: string | undefined = undefined;
recipeDetailForm = this._formBuilder.group({
productCode: '',
name: '',
otherName: '',
description: '',
otherDescription: '',
lastModified: Date(),
price: 0,
isUse: false,
isShow: false,
disable: false,
});
repl = [];
tpl = [];
toppingSet: ToppingSet[] | null = null;
submenus: Recipe01[] | null = null;
rawRecipe: {} | undefined | null = undefined;
async ngOnInit() {
this.productCode = this._route.snapshot.params['productCode'];
this.recipeDetail$ = (
await this._recipeService.getRecipeDetail(this.productCode)
).pipe(first());
this.recipeDetail$.subscribe((detail) => {
console.log('Recipe Detail', detail);
// transform lastChange aka lastUpdated to type `Date`
if(detail.lastUpdated){
console.log("Date ", detail.lastUpdated, typeof detail.lastUpdated)
}
this.recipeDetailForm.patchValue(detail);
console.log("from recipeDetailForm", this.recipeDetailForm);
this.recipeDetailForm.get('lastModified')?.setValue(detail.lastUpdated.toString());
this.isLoaded = true;
this.recipeOriginalDetail = { ...this.recipeDetailForm.getRawValue() };
});
this._recipeService
.getSubMenus(
await this._recipeService.getCurrentCountry(),
this._recipeService.getCurrentFile(),
this.productCode
)
.subscribe((data) => {
console.log('Submenus', data);
this.submenus = data;
});
this.recipeDetailForm.valueChanges.subscribe(this.onRecipeDetailFormChange);
(
await this._toppingService.getToppingsOfRecipe(
this.department,
this._recipeService.getCurrentFile(),
this.productCode
)
).subscribe((data) => {
this.toppingSet = data;
// console.log('Toppings', data);
});
// get full raw value of this recipe
(
await this._recipeService.getRawRecipeOfProductCode(
this.department,
this._recipeService.getCurrentFile(),
this.productCode
)
).subscribe((data) => {
console.log('Raw Recipe', data);
this.rawRecipe = data;
});
// snap recipe detail form value
this.actionRecord.registerOnAddAction((currAction, allAction) => {
if (currAction.type === 'recipeListData') {
switch (currAction.action) {
case 'add':
break;
case 'delete':
break;
}
}
console.log('Action Record', allAction);
});
}
showConfirmSaveModal: EventEmitter<boolean> = new EventEmitter<boolean>();
showConfirmCloseModal: EventEmitter<boolean> = new EventEmitter<boolean>();
confirmSave = {
title: 'The changes detected!',
message: 'Do you want to save changes?',
confirmCallBack: async () => {
console.log('confirm save');
// get username
let username: string = '';
username = this._userService.getCurrentUser()!.name;
// diff with rawValue, then send
let to_send = {
edit_by: username,
commit_msg: this.commit_msg,
productCode:
this.changedProductCode == undefined
? this.productCode
: this.changedProductCode,
name:
this.recipeDetailForm.getRawValue().name !=
this.recipeOriginalDetail.name
? this.recipeDetailForm.getRawValue().name
: this.recipeOriginalDetail.name,
otherName:
this.recipeDetailForm.getRawValue().otherName !=
this.recipeOriginalDetail.otherName
? this.recipeDetailForm.getRawValue().otherName
: this.recipeOriginalDetail.otherName,
description:
this.recipeDetailForm.getRawValue().description !=
this.recipeOriginalDetail.description
? this.recipeDetailForm.getRawValue().description
: this.recipeOriginalDetail.description,
otherDescription:
this.recipeDetailForm.getRawValue().otherDescription !=
this.recipeOriginalDetail.otherDescription
? this.recipeDetailForm.getRawValue().otherDescription
: this.recipeOriginalDetail.otherDescription,
LastChange: new Date(),
price:
this.recipeDetailForm.getRawValue().price !=
this.recipeOriginalDetail.price
? this.recipeDetailForm.getRawValue().price
: this.recipeOriginalDetail.price,
isUse: (this.rawRecipe as any).isUse,
isShow: (this.rawRecipe as any).isShow,
disable: (this.rawRecipe as any).disable,
recipes: [...(this.repl.length <= 0 ? [] : this.repl)],
SubMenu: [...(this.rawRecipe! as any).SubMenu!],
ToppingSet: [...(this.rawRecipe as any).ToppingSet],
};
console.log('pre to_send', to_send);
this.concatNoEditKeyToMap(this.rawRecipe, to_send);
console.log('to_send', to_send);
this._recipeService.editChanges(
await this._recipeService.getCurrentCountry(this.department),
this._recipeService.getCurrentFile(),
{
...to_send,
}
);
console.log('Sending changes');
void this._router
.navigate(['/' + this.department + '/recipes'])
.then(() => {
window.location.reload();
});
},
};
onKeyUpCommitMsg(e: any) {
this.commit_msg = e.target.value;
}
confirmClose = {
title: 'The changes will be lost!',
message: 'Do you want to close without saving?',
confirmCallBack: () => {
console.log('confirm close');
this._router.navigate(['/' + this.department + '/recipes']);
},
};
onPressConfirmSave() {
if (this.isValueChanged) {
this.showConfirmSaveModal.emit(true);
} else {
this._router.navigate(['/' + this.department + '/recipes']);
}
}
onPressConfirmClose() {
if (this.isValueChanged) {
this.showConfirmCloseModal.emit(true);
} else {
this._router.navigate(['/' + this.department + '/recipes']);
}
}
isValueChanged: boolean = false;
onRecipeDetailFormChange(recipeDetail: typeof this.recipeDetailForm.value) {
// console.log('Recipe Detail Form Changed', recipeDetail);
}
onRecipeListFormChange(repl: unknown[]) {
console.log('Recipe List Form Changed', repl);
this.tpl = repl[0] as never[];
this.repl = repl[1] as never[];
console.log('Recipe List Form Changed', this.repl, this.tpl);
for (let ti = 0; ti < this.tpl.length; ti++) {
// check at the same index
if (!isEqual(this.tpl[ti][0], (this.rawRecipe as any).ToppingSet[ti])) {
console.log(
'topping list changed',
ti,
this.tpl[ti][0],
(this.rawRecipe as any).ToppingSet[ti]
);
// update raw recipe
(this.rawRecipe as any).ToppingSet[ti] = this.tpl[ti][0];
console.log(
'after update topping',
(this.rawRecipe as any).ToppingSet[ti]
);
}
}
// console.log('Recipe List Form Changed', this.repl, this.tpl);
this.isValueChanged ||= repl != undefined;
}
onToppingListChange(tpl: unknown[]) {
// console.log('Topping List Form Changed', tpl);
this.tpl = tpl as never[];
this.isValueChanged ||= tpl != undefined;
}
isEditable() {
return this._userService
.getCurrentUser()!
.permissions.includes(UserPermissions.EDITOR);
}
onProductCodeChange(event: any) {
if (event.target.value != '') {
this.changedProductCode = event.target.value;
}
}
// Submenus
selectedSubProductCode: string | undefined = undefined;
hasSubmenu = () => this.submenus != null && this.submenus!.length > 0;
listSubMenuProductcodes = () =>
this.submenus!.map((recipe) => recipe.productCode);
selectSubmenu(productCode: string) {
void this._router.navigate([
'/' + this.department + '/recipes/' + productCode,
]);
}
// concat remaining unused keys
concatNoEditKeyToMap(source: any, target: any) {
for (const key of Object.keys(source)) {
if (!Object.keys(target).includes(key)) {
target[key] = source[key];
}
}
}
recipePrice = () =>
this.rawRecipe != undefined &&
this.rawRecipe != null &&
Object.keys(this.rawRecipe as any).includes('cashPrice')
? (this.rawRecipe as any).cashPrice
: 0;
// image path
imagePath = (productCode: string) => {
const filename = this._recipeService.getCurrentFile();
return environment.api +
'/recipes/' +
this.department +
'/' +
filename +
'/' +
productCode +
'/image';
};
}
import { CommonModule, DatePipe } from "@angular/common";
import { Component, EventEmitter, OnInit } from "@angular/core";
import { FormBuilder, FormsModule, ReactiveFormsModule } from "@angular/forms";
import { ActivatedRoute, Router, RouterLink } from "@angular/router";
import { Observable, first, 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 { RecipeListComponent } from "./recipe-list/recipe-list.component";
import {
Recipe01,
RecipeDetail,
RecipeDetailMat,
Topping,
ToppingSet,
} from "src/app/core/models/recipe.model";
import { ActionRecord } from "src/app/shared/actionRecord/actionRecord";
import { UserService } from "src/app/core/services/user.service";
import { UserPermissions } from "src/app/core/auth/userPermissions";
import { ToppingService } from "src/app/core/services/topping.service";
import { copy, transformToTSV } from "src/app/shared/helpers/copy";
import { isEqual } from "lodash";
import { environment } from "src/environments/environment";
@Component({
selector: "app-recipe-details",
templateUrl: "./recipe-details.component.html",
standalone: true,
animations: [
trigger("inOutAnimation", [
transition(":enter", [
style({ opacity: 0 }),
animate("1s ease-out", style({ opacity: 1 })),
]),
]),
],
imports: [
CommonModule,
RouterLink,
ReactiveFormsModule,
ConfirmModal,
DatePipe,
RecipeListComponent,
FormsModule,
],
})
export class RecipeDetailsComponent implements OnInit {
title: string = "Recipe Detail";
recipeDetail$!: Observable<RecipeDetail>;
isLoaded: boolean = false;
isMatLoaded: boolean = false;
actionRecord: ActionRecord<RecipeDetail | RecipeDetailMat> =
new ActionRecord();
recipeOriginalDetail!: typeof this.recipeDetailForm.value;
commit_msg: string = "";
//
department: string = this._route.parent!.snapshot.params["department"];
constructor(
private _formBuilder: FormBuilder,
private _route: ActivatedRoute,
private _router: Router,
private _recipeService: RecipeService,
private _toppingService: ToppingService,
private _userService: UserService,
) {}
productCode!: any;
changedProductCode: string | undefined = undefined;
recipeDetailForm = this._formBuilder.group({
productCode: "",
name: "",
otherName: "",
description: "",
otherDescription: "",
lastModified: Date(),
price: 0,
isUse: false,
isShow: false,
disable: false,
});
repl = [];
tpl = [];
toppingSet: ToppingSet[] | null = null;
submenus: Recipe01[] | null = null;
rawRecipe: {} | undefined | null = undefined;
async ngOnInit() {
this.productCode = this._route.snapshot.params["productCode"];
this.recipeDetail$ = (
await this._recipeService.getRecipeDetail(this.productCode)
).pipe(first());
this.recipeDetail$.subscribe((detail) => {
console.log("Recipe Detail", detail);
// transform lastChange aka lastUpdated to type `Date`
if (detail.lastUpdated) {
console.log("Date ", detail.lastUpdated, typeof detail.lastUpdated);
}
this.recipeDetailForm.patchValue(detail);
console.log("from recipeDetailForm", this.recipeDetailForm);
this.recipeDetailForm
.get("lastModified")
?.setValue(detail.lastUpdated.toString());
this.isLoaded = true;
this.recipeOriginalDetail = { ...this.recipeDetailForm.getRawValue() };
});
this._recipeService
.getSubMenus(
await this._recipeService.getCurrentCountry(),
this._recipeService.getCurrentFile(),
this.productCode,
)
.subscribe((data) => {
console.log("Submenus", data);
this.submenus = data;
});
this.recipeDetailForm.valueChanges.subscribe(this.onRecipeDetailFormChange);
(
await this._toppingService.getToppingsOfRecipe(
this.department,
this._recipeService.getCurrentFile(),
this.productCode,
)
).subscribe((data) => {
this.toppingSet = data;
// console.log('Toppings', data);
});
// get full raw value of this recipe
(
await this._recipeService.getRawRecipeOfProductCode(
this.department,
this._recipeService.getCurrentFile(),
this.productCode,
)
).subscribe((data) => {
console.log("Raw Recipe", data);
this.rawRecipe = data;
});
// snap recipe detail form value
this.actionRecord.registerOnAddAction((currAction, allAction) => {
if (currAction.type === "recipeListData") {
switch (currAction.action) {
case "add":
break;
case "delete":
break;
}
}
console.log("Action Record", allAction);
});
}
showConfirmSaveModal: EventEmitter<boolean> = new EventEmitter<boolean>();
showConfirmCloseModal: EventEmitter<boolean> = new EventEmitter<boolean>();
confirmSave = {
title: "The changes detected!",
message: "Do you want to save changes?",
confirmCallBack: async () => {
console.log("confirm save");
// get username
let username: string = "";
username = this._userService.getCurrentUser()!.name;
// diff with rawValue, then send
let to_send = {
edit_by: username,
commit_msg: this.commit_msg,
productCode:
this.changedProductCode == undefined
? this.productCode
: this.changedProductCode,
name:
this.recipeDetailForm.getRawValue().name !=
this.recipeOriginalDetail.name
? this.recipeDetailForm.getRawValue().name
: this.recipeOriginalDetail.name,
otherName:
this.recipeDetailForm.getRawValue().otherName !=
this.recipeOriginalDetail.otherName
? this.recipeDetailForm.getRawValue().otherName
: this.recipeOriginalDetail.otherName,
description:
this.recipeDetailForm.getRawValue().description !=
this.recipeOriginalDetail.description
? this.recipeDetailForm.getRawValue().description
: this.recipeOriginalDetail.description,
otherDescription:
this.recipeDetailForm.getRawValue().otherDescription !=
this.recipeOriginalDetail.otherDescription
? this.recipeDetailForm.getRawValue().otherDescription
: this.recipeOriginalDetail.otherDescription,
LastChange: new Date(),
price:
this.recipeDetailForm.getRawValue().price !=
this.recipeOriginalDetail.price
? this.recipeDetailForm.getRawValue().price
: this.recipeOriginalDetail.price,
isUse: (this.rawRecipe as any).isUse,
isShow: (this.rawRecipe as any).isShow,
disable: (this.rawRecipe as any).disable,
recipes: [...(this.repl.length <= 0 ? [] : this.repl)],
SubMenu: [...(this.rawRecipe! as any).SubMenu!],
ToppingSet: [...(this.rawRecipe as any).ToppingSet],
};
console.log("pre to_send", to_send);
this.concatNoEditKeyToMap(this.rawRecipe, to_send);
console.log("to_send", to_send);
this._recipeService.editChanges(
await this._recipeService.getCurrentCountry(this.department),
this._recipeService.getCurrentFile(),
{
...to_send,
},
);
console.log("Sending changes");
void this._router
.navigate(["/" + this.department + "/recipes"])
.then(() => {
window.location.reload();
});
},
};
onKeyUpCommitMsg(e: any) {
this.commit_msg = e.target.value;
}
confirmClose = {
title: "The changes will be lost!",
message: "Do you want to close without saving?",
confirmCallBack: () => {
console.log("confirm close");
this._router.navigate(["/" + this.department + "/recipes"]);
},
};
onPressConfirmSave() {
if (this.isValueChanged) {
this.showConfirmSaveModal.emit(true);
} else {
this._router.navigate(["/" + this.department + "/recipes"]);
}
}
onPressConfirmClose() {
if (this.isValueChanged) {
this.showConfirmCloseModal.emit(true);
} else {
this._router.navigate(["/" + this.department + "/recipes"]);
}
}
isValueChanged: boolean = false;
onRecipeDetailFormChange(recipeDetail: typeof this.recipeDetailForm.value) {
// console.log('Recipe Detail Form Changed', recipeDetail);
}
onRecipeListFormChange(repl: unknown[]) {
console.log("Recipe List Form Changed", repl);
this.tpl = repl[0] as never[];
this.repl = repl[1] as never[];
console.log("Recipe List Form Changed", this.repl, this.tpl);
for (let ti = 0; ti < this.tpl.length; ti++) {
// check at the same index
if (!isEqual(this.tpl[ti][0], (this.rawRecipe as any).ToppingSet[ti])) {
console.log(
"topping list changed",
ti,
this.tpl[ti][0],
(this.rawRecipe as any).ToppingSet[ti],
);
// update raw recipe
(this.rawRecipe as any).ToppingSet[ti] = this.tpl[ti][0];
console.log(
"after update topping",
(this.rawRecipe as any).ToppingSet[ti],
);
}
}
// console.log('Recipe List Form Changed', this.repl, this.tpl);
this.isValueChanged ||= repl != undefined;
}
onToppingListChange(tpl: unknown[]) {
// console.log('Topping List Form Changed', tpl);
this.tpl = tpl as never[];
this.isValueChanged ||= tpl != undefined;
}
isEditable() {
return this._userService
.getCurrentUser()!
.permissions.includes(UserPermissions.EDITOR);
}
onProductCodeChange(event: any) {
if (event.target.value != "") {
this.changedProductCode = event.target.value;
}
}
// Submenus
selectedSubProductCode: string | undefined = undefined;
hasSubmenu = () => this.submenus != null && this.submenus!.length > 0;
listSubMenuProductcodes = () =>
this.submenus!.map((recipe) => recipe.productCode);
selectSubmenu(productCode: string) {
void this._router.navigate([
"/" + this.department + "/recipes/" + productCode,
]);
}
// concat remaining unused keys
concatNoEditKeyToMap(source: any, target: any) {
for (const key of Object.keys(source)) {
if (!Object.keys(target).includes(key)) {
target[key] = source[key];
}
}
}
recipePrice = () =>
this.rawRecipe != undefined &&
this.rawRecipe != null &&
Object.keys(this.rawRecipe as any).includes("cashPrice")
? (this.rawRecipe as any).cashPrice
: 0;
// image path
imagePath = (productCode: string) => {
const filename = this._recipeService.getCurrentFile();
return (
environment.api +
"/recipes/" +
this.department +
"/" +
filename +
"/" +
productCode +
"/image"
);
};
}