change display, add StringParam (WIP)

This commit is contained in:
pakintada@gmail.com 2024-01-09 17:11:15 +07:00
parent dd1c072201
commit 98341d2d80
11 changed files with 352 additions and 125 deletions

View file

@ -29,6 +29,7 @@ export type RecipeDetail = {
};
export type RecipeDetailMat = {
StringParam: string;
isUse: boolean;
materialID: number;
name: string;
@ -75,7 +76,6 @@ export interface Recipe01 {
OnTOP: string;
LastChange: Date;
MenuStatus: string;
RemainingCups: string;
StringParam: string;
TextForWarningBeforePay: string[];
cashPrice: number;
@ -142,6 +142,7 @@ export interface ToppingList {
}
export interface MatRecipe {
StringParam: string;
MixOrder: number;
FeedParameter: number;
FeedPattern: number;
@ -164,6 +165,7 @@ export interface ToppingSet {
}
export interface MaterialSetting {
StringParam: string,
AlarmIDWhenOffline: string;
BeanChannel: string;
CanisterType: string;

View file

@ -12,6 +12,18 @@
<h5 class="mb-2 text-xl font-bold text-gray-900">
{{ recipeDetailForm.getRawValue().otherName }}
</h5>
<!-- productCode -->
<div>
<input
class="input text-lg text-gray-900 my-2"
type="text"
name="productCode"
[value]="productCode"
(keyup)="onProductCodeChange($event)"
[disabled]="!isEditable()"
/>
</div>
</div>
<div class="flex items-center mb-2">
<div class="flex items-center">
@ -296,20 +308,20 @@
</div>
</div>
<div
class="sticky bottom-0 col-span-3 flex justify-end bg-white rounded-full drop-shadow-2xl p-3"
class="sticky bottom-0 col-span-3 flex justify-end bg-white rounded-full drop-shadow-2xl p-3"
>
<!-- <div> Commit Message </div> -->
<!-- <p class="text-2xl mr-8 text-gray-400 dark:text-gray-500">Commit Message</p> -->
<input
type="text"
name="commit-message"
id="commit-message"
placeholder="Commit Message"
class="input input-bordered mr-8 w-full max-w-xs"
[value]="productCode"
(keyup)="onKeyUpCommitMsg($event)"
[disabled]="!isEditable()"
/>
<!-- <div> Commit Message </div> -->
<!-- <p class="text-2xl mr-8 text-gray-400 dark:text-gray-500">Commit Message</p> -->
<input
type="text"
name="commit-message"
id="commit-message"
placeholder="Commit Message"
class="input input-bordered mr-8 w-full max-w-xs"
[value]="productCode"
(keyup)="onKeyUpCommitMsg($event)"
[disabled]="!isEditable()"
/>
<button
(click)="onPressConfirmClose()"
class="btn btn-error w-36 text-white mr-2"

View file

@ -1,6 +1,6 @@
import { CommonModule, DatePipe } from '@angular/common';
import { Component, EventEmitter, OnInit } from '@angular/core';
import { FormBuilder, ReactiveFormsModule } from '@angular/forms';
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';
@ -41,7 +41,8 @@ import { RecipeToppingsetComponent } from "./recipe-toppingset/recipe-toppingset
ConfirmModal,
DatePipe,
RecipeListComponent,
RecipeToppingsetComponent
RecipeToppingsetComponent,
FormsModule
]
})
export class RecipeDetailsComponent implements OnInit {
@ -71,7 +72,8 @@ export class RecipeDetailsComponent implements OnInit {
private _userService: UserService
) {}
productCode!: string;
productCode!: any;
changedProductCode: string | undefined = undefined;
recipeDetailForm = this._formBuilder.group({
productCode: '',
@ -111,7 +113,7 @@ export class RecipeDetailsComponent implements OnInit {
this._toppingService.getToppingsOfRecipe(this.department, this._recipeService.getCurrentFile(), this.productCode).subscribe((data) => {
this.toppingSet = data;
console.log('Toppings', data);
// console.log('Toppings', data);
})
// snap recipe detail form value
@ -147,7 +149,7 @@ export class RecipeDetailsComponent implements OnInit {
let to_send = {
edit_by: username,
commit_msg: this.commit_msg,
productCode: this.productCode,
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,
@ -225,7 +227,7 @@ export class RecipeDetailsComponent implements OnInit {
}
onToppingListChange(tpl: unknown[]) {
console.log('Topping List Form Changed', tpl);
// console.log('Topping List Form Changed', tpl);
this.tpl = tpl as never[];
this.isValueChanged ||= tpl != undefined;
@ -235,4 +237,10 @@ export class RecipeDetailsComponent implements OnInit {
return this._userService.getCurrentUser()!.permissions.includes(UserPermissions.EDITOR);
}
onProductCodeChange(event: any) {
if(event.target.value != ""){
this.changedProductCode = event.target.value;
}
}
}

View file

@ -4,14 +4,7 @@
<th class="px-6 py-3">Is Use</th>
<th class="px-6 py-3">Material ID</th>
<th class="px-6 py-3">Material Name</th>
<th class="px-6 py-3">MixOrder</th>
<th class="px-6 py-3">Stir Time</th>
<th class="px-6 py-3">Powder Gram</th>
<th class="px-6 py-3">Powder Time</th>
<th class="px-6 py-3">Syrup Gram</th>
<th class="px-6 py-3">Syrup Time</th>
<th class="px-6 py-3">Water Cold</th>
<th class="px-6 py-3">Water Yield</th>
<th class="px-6 py-3">Settings</th>
</tr>
</thead>
<tbody
@ -30,33 +23,69 @@
(click)="openMaterialList(i)"
/>
</td>
<td class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap">
<input type="text" class="input" formControlName="name" />
</td>
<td class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap">
<input type="text" class="input" formControlName="mixOrder" />
</td>
<td class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap">
<input type="text" class="input" formControlName="powderGram" />
</td>
<td class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap">
<input type="text" class="input" formControlName="powderTime" />
</td>
<td class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap">
<input type="text" class="input" formControlName="syrupGram" />
</td>
<td class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap">
<input type="text" class="input" formControlName="syrupTime" />
</td>
<td class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap">
<input type="text" class="input" formControlName="waterCold" />
</td>
<td class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap">
<input type="text" class="input" formControlName="waterYield" />
</td>
<td class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap">
<input type="text" class="input" formControlName="stirTime" />
</td>
<!-- powder -->
<div *ngIf="getTypeForRecipeListAtIndex(i)['category'] == 'powder'">
<td class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap">
<input type="text" class="input" formControlName="name" />
</td>
<td class="m-2 px-4 py-4 font-medium text-gray-900 whitespace-nowrap">
<div class="flex items-center">
<p>Volume=&nbsp;</p>
<input type="text" class="input w-16" formControlName="powderGram" />
<p>&nbsp;gram</p>
</div>
</td>
</div>
<!-- syrup -->
<div *ngIf="getTypeForRecipeListAtIndex(i)['category'] == 'syrup'">
<td class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap">
<input type="text" class="input" formControlName="name" />
</td>
<td class="m-2 px-4 py-4 font-medium text-gray-900 whitespace-nowrap">
<div class="flex items-center">
<p>Volume=&nbsp;</p>
<input type="text" class="input w-16" formControlName="syrupGram" />
<p>&nbsp;gram</p>
</div>
</td>
</div>
<!-- bean -->
<div *ngIf="getTypeForRecipeListAtIndex(i)['category'] == 'bean'">
<td class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap">
<input type="text" class="input" formControlName="name" />
</td>
<td class="m-2 px-4 py-4 font-medium text-gray-900 whitespace-nowrap">
<div class="flex items-center">
<p>StringParam=</p>
<input type="text" class="input w-16" formControlName="StringParam" />
<p>&nbsp;</p>
<p>Volume=&nbsp;</p>
<input type="text" class="input w-16" formControlName="powderGram" />
<p>&nbsp;gram</p>
</div>
<div class="flex items-center" *ngIf="getTypeForRecipeListAtIndex(i)['id'] == 1002">
<p>Hot=&nbsp;</p>
<input type="text" class="input w-16" formControlName="waterYield" />
<p>&nbsp;ml&nbsp;</p>
<p>Grinder=&nbsp;</p><input type="text" class="input w-16" formControlName="stirTime" /><p>&nbsp;sec</p>
</div>
</td>
</div>
<!-- others -->
<div *ngIf="(isNotExistbyCatagories(getTypeForRecipeListAtIndex(i)['id']) || isEquipment(getTypeForRecipeListAtIndex(i)['id']))">
<td class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap">
<input type="text" class="input" formControlName="name" />
</td>
</div>
</tr>
</tbody>
</table>
@ -75,18 +104,23 @@
<div class="flex flex-row m-2 modal">
<p class="font-bold text-lg m-2">Materials</p>
</div>
<div
*ngFor="let material of fullMaterialList"
class="flex flex-row m-2 overflow-y-scroll"
>
<button
class="btn bg-primary btn-md border-2 text-base text-gray-700"
(click)="selectMaterial(currentSelectRecipeList!, material.materialId)"
>
{{ material.materialId }}
</button>
<h3 class="m-3">{{ material.name }}</h3>
<p class="m-3">{{ material.type }}</p>
<div *ngFor="let cat of getCategoriesList()">
<details class="dropdown">
<summary class="m-1 btn">{{ cat }}</summary>
<ul class="mx-4 menu p-2 shadow bg-base-100 rounded-box w-auto">
<li
class="my-1 mx-4"
*ngFor="let material of categoriedMaterial[cat]"
>
<a
class="btn"
(click)="selectMaterial(currentSelectRecipeList!, material.id)"
>{{ material.name }} ({{ material.id }})</a
>
</li>
</ul>
</details>
</div>
</div>
</label>

View file

@ -22,6 +22,7 @@ import { UserService } from 'src/app/core/services/user.service';
import { Action, ActionRecord } from 'src/app/shared/actionRecord/actionRecord';
import { FormsModule } from '@angular/forms';
import { NgSelectModule } from '@ng-select/ng-select';
import { getMaterialType, getCategories, isNonMaterial } from 'src/app/shared/helpers/mat_type';
@Component({
selector: 'app-recipe-list',
@ -35,13 +36,17 @@ export class RecipeListComponent implements OnInit {
materialList: MaterialCode[] = [];
fullMaterialList: { materialId: number; name: string; type: string; }[] | null = [];
fullMaterialList:
| { materialId: number; name: string; type: string }[]
| null = [];
showMaterialSelector: boolean = false;
currentSelectRecipeList: number | null = null;
isMatLoaded: boolean = false;
categoriedMaterial: { [key: string]: { id: number; name: string }[] } = {};
constructor(
private _recipeService: RecipeService,
private _materialService: MaterialService,
@ -67,17 +72,70 @@ export class RecipeListComponent implements OnInit {
result.forEach((recipeDetailMat: RecipeDetailMat) => {
this.recipeListData.push(
this._formBuilder.group({
isUse: [{ value: recipeDetailMat.isUse, disabled: !this.isEditable()}],
materialPathId: [{value:recipeDetailMat.materialPathId, disabled: !this.isEditable()}],
StringParam: [
{
value: recipeDetailMat.StringParam,
disabled: !this.isEditable(),
}
],
isUse: [
{ value: recipeDetailMat.isUse, disabled: !this.isEditable() },
],
materialPathId: [
{
value: recipeDetailMat.materialPathId,
disabled: !this.isEditable(),
},
],
name: [{ value: recipeDetailMat.name, disabled: true }],
mixOrder: [{ value:recipeDetailMat.mixOrder, disabled: !this.isEditable()}],
stirTime: [{value:recipeDetailMat.stirTime, disabled: !this.isEditable()}],
powderGram: [{value:recipeDetailMat.powderGram, disabled: !this.isEditable()}],
powderTime: [{value:recipeDetailMat.powderTime, disabled: !this.isEditable()}],
syrupGram: [{value:recipeDetailMat.syrupGram, disabled: !this.isEditable()}],
syrupTime: [{value: recipeDetailMat.syrupTime, disabled: !this.isEditable()}],
waterCold: [{value:recipeDetailMat.waterCold, disabled: !this.isEditable()}],
waterYield: [{value:recipeDetailMat.waterYield, disabled: !this.isEditable()}],
mixOrder: [
{
value: recipeDetailMat.mixOrder,
disabled: !this.isEditable(),
},
],
stirTime: [
{
value: recipeDetailMat.stirTime,
disabled: !this.isEditable(),
},
],
powderGram: [
{
value: recipeDetailMat.powderGram,
disabled: !this.isEditable(),
},
],
powderTime: [
{
value: recipeDetailMat.powderTime,
disabled: !this.isEditable(),
},
],
syrupGram: [
{
value: recipeDetailMat.syrupGram,
disabled: !this.isEditable(),
},
],
syrupTime: [
{
value: recipeDetailMat.syrupTime,
disabled: !this.isEditable(),
},
],
waterCold: [
{
value: recipeDetailMat.waterCold,
disabled: !this.isEditable(),
},
],
waterYield: [
{
value: recipeDetailMat.waterYield,
disabled: !this.isEditable(),
},
],
})
);
});
@ -86,29 +144,27 @@ export class RecipeListComponent implements OnInit {
this.recipeListForm.valueChanges.subscribe((value) => {
// console.log(value.recipeListData);
// console.log(this._recipeListOriginalArray);
// console.log("original recipe detail",this._recipeListOriginalArray);
if (
!isEqual(
sortBy(value, 'materialID'),
sortBy(this._recipeListOriginalArray, 'materialID')
)
) {
let emitted_res: any[] = []
let emitted_res: any[] = [];
// force type change. temporary solution
forEach(value.recipeListData!, (recipeDetailMat: any) => {
recipeDetailMat.materialPathId = parseInt(recipeDetailMat.materialPathId!)
emitted_res.push(recipeDetailMat)
})
recipeDetailMat.materialPathId = parseInt(
recipeDetailMat.materialPathId!
);
emitted_res.push(recipeDetailMat);
});
this.recipeListFormChange.emit(emitted_res as unknown[]);
} else {
this.recipeListFormChange.emit([]);
}
});
// TODO: make this
@ -118,28 +174,95 @@ export class RecipeListComponent implements OnInit {
this._materialService.getFullMaterialDetail().subscribe((materials) => {
this.fullMaterialList = materials;
})
this.categoriedMaterial = this.ListCategory();
console.log(this.categoriedMaterial);
});
}
get recipeListData(): FormArray {
return this.recipeListForm.get('recipeListData') as FormArray;
}
isEditable(){
return this._userService.getCurrentUser()!.permissions.includes(UserPermissions.EDITOR);
isEditable() {
return this._userService
.getCurrentUser()!
.permissions.includes(UserPermissions.EDITOR);
}
openMaterialList(i: any){
console.log("open material list for ", i);
openMaterialList(i: any) {
console.log('open material list for ', i);
this.showMaterialSelector = true;
this.currentSelectRecipeList = i;
}
selectMaterial(i: number, material: number){
selectMaterial(i: number, material: number) {
// console.log("make material list by category", this.makeListCategory());
this.showMaterialSelector = false;
this.recipeListData.at(i).get('materialPathId')?.setValue(material);
console.log("set mat ", material, "to slot", i);
console.log('set mat ', material, 'to slot', i);
}
getTypeForRecipeListAtIndex(i: any){
let target = this.recipeListData.at(i);
// search from full detail
for(const category of Object.keys(this.categoriedMaterial)){
let finder = this.categoriedMaterial[category].find(mat => mat.id == target.value.materialPathId);
if (finder != undefined) {
// console.log('found ', finder.name, ' in ', category);
return {
"category": category,
"name": finder.name,
"id": finder.id
};
}
}
// console.log("did not find in full detail");
return {
"category": "others",
"name": target.value.name,
"id": target.value.materialPathId
};
}
// TODO: Filter from full detail by type
ListCategory = () => {
let catMap: { [key: string]: any[] } = {
'others': []
};
// create category map
getCategories().forEach((category) => {
catMap[category] = [];
});
console.log("generated category", catMap);
this.fullMaterialList!.forEach((mat) => {
let category = getMaterialType(mat.materialId);
if(Array.isArray(catMap[category])){
catMap[category].push({
id: mat.materialId,
name: mat.name,
});
}
});
return catMap;
};
getCategoriesList = () => Object.keys(this.categoriedMaterial);
// exposed from mat_type.ts
isEquipment = (materialId: number) => isNonMaterial(materialId);
isNotExistbyCatagories = (materialId : number) => getMaterialType(materialId) == 'others';
}

View file

@ -99,7 +99,7 @@ export class RecipeToppingsetComponent implements OnInit {
)
.subscribe((data) => {
this.allToppings = data;
console.log('allToppings', data);
// console.log('allToppings', data);
data.ToppingGroup.forEach((group: ToppingGroup) => {
if (this.allToppingsDefinitions != null) {
@ -118,8 +118,8 @@ export class RecipeToppingsetComponent implements OnInit {
}
});
console.log(this.allToppingsDefinitions);
console.log('allToppingMembersByGroup', this.allToppingMembersByGroup);
// console.log(this.allToppingsDefinitions);
// console.log('allToppingMembersByGroup', this.allToppingMembersByGroup);
});
this.toppingForm.valueChanges.subscribe((value) => {
@ -157,7 +157,7 @@ export class RecipeToppingsetComponent implements OnInit {
// console.log('newToppingList', newToppingSetList);
this.toppingSetChange.emit(newToppingSetList as unknown[]);
} else {
console.log('newToppingListNoChange', value.toppingList);
// console.log('newToppingListNoChange', value.toppingList);
this.toppingSetChange.emit([]);
}
});

View file

@ -0,0 +1,45 @@
var rangeMaterialMapping: { [key: string]: (id: number) => boolean } = {
soda: (id: number) => id == 1031,
water: (id: number) => id == 1,
ice: (id: number) => id == 9100,
whipper: (id: number) => id == 8102,
bean: (id: number) => inRange(1001, 1009, id) || inRange(1100, 1199, id),
leaves: (id: number) => inRange(1600, 1799, id),
syrup: (id: number) =>
inRange(1032, 1039, id) ||
inRange(1020, 1030, id) ||
inRange(1200, 1299, id),
powder: (id: number) => inRange(1040, 1080, id) || inRange(1300, 1399, id),
cup: (id: number) => inRange(9500, 9549, id),
lid: (id: number) => inRange(9600, 9649, id),
straw: (id: number) => inRange(9700, 9749, id),
icecream: (id: number) => inRange(2100, 2200, id),
};
export function inRange(min: number, max: number, value: number) {
// console.log(min, max, value, value >= min && value <= max);
return value >= min && value <= max;
}
export function getCategories() {
return Object.keys(rangeMaterialMapping);
}
export function getMaterialType(materialId: number) {
for (const key of Object.keys(rangeMaterialMapping)) {
if (rangeMaterialMapping[key](materialId)) {
return key;
}
}
return 'others';
}
export function isNonMaterial(materialId: number) {
// test cup, lid, straw
return (
rangeMaterialMapping['cup'](materialId) ||
rangeMaterialMapping['lid'](materialId) ||
rangeMaterialMapping['straw'](materialId) || rangeMaterialMapping['whipper'](materialId)
);
}