fix(merge_component): 🐛 fix data lost after applied from merge

Fixing data lost after pressed on apply button in merge modal, WIP selection merge
This commit is contained in:
pakintada@gmail.com 2024-03-19 10:44:25 +07:00
parent cd0f67bb44
commit 58746ebdfb
5 changed files with 182 additions and 50 deletions

View file

@ -34,6 +34,7 @@ import { FormsModule } from '@angular/forms';
import { RecipeListComponent } from '../recipes/recipe-details/recipe-list/recipe-list.component'; import { RecipeListComponent } from '../recipes/recipe-details/recipe-list/recipe-list.component';
import { ResizeEvent, ResizableModule } from 'angular-resizable-element'; import { ResizeEvent, ResizableModule } from 'angular-resizable-element';
import { Debugger } from 'src/app/shared/helpers/debugger'; import { Debugger } from 'src/app/shared/helpers/debugger';
import { convertFromInterProductCode, inRange } from 'src/app/shared/helpers/recipe';
@Component({ @Component({
selector: 'app-merge', selector: 'app-merge',
@ -442,7 +443,12 @@ export class MergeComponent
} }
} }
console.log("fromMachine",this.recipeFromMachine);
if (Object.keys(this.recipeFromMachine).length > 0) { if (Object.keys(this.recipeFromMachine).length > 0) {
// cat master to target
this.concatNoEditKeyToMap(this.recipeFromMachine, this.targetRecipe[this.getCommitAttr(this.selectedCommit, 'contents').productCode]);
to_send['appliedMachineRecipe'] = this.recipeFromMachine; to_send['appliedMachineRecipe'] = this.recipeFromMachine;
} }
@ -455,6 +461,8 @@ export class MergeComponent
console.log('sending upgrade', to_send); console.log('sending upgrade', to_send);
// alert("sending .. ")
this._recipeService this._recipeService
.upgradeRecipe( .upgradeRecipe(
await this._recipeService.getCurrentCountry(), await this._recipeService.getCurrentCountry(),
@ -508,6 +516,7 @@ export class MergeComponent
// get current pd // get current pd
let pd = this.getCommitAttr(this.selectedCommit, 'contents').productCode; let pd = this.getCommitAttr(this.selectedCommit, 'contents').productCode;
console.log("check content", compare(this.targetRecipe[pd], this.getCommitAttr(this.selectedCommit, 'contents')));
if (base != '') { if (base != '') {
switch (base) { switch (base) {
@ -523,6 +532,11 @@ export class MergeComponent
this.getCommitAttr(this.selectedCommit, 'contents').recipes[idx] = this.getCommitAttr(this.selectedCommit, 'contents').recipes[idx] =
diff_recipe.recipes[idx]; diff_recipe.recipes[idx];
// TODO: add topping sync, if is topping slot, set topping too! // TODO: add topping sync, if is topping slot, set topping too!
if(inRange(8111, 8130, convertFromInterProductCode(diff_recipe.recipes[idx].materialPathId))){
let toppingSlot = convertFromInterProductCode(diff_recipe.recipes[idx].materialPathId )- 8110;
this.getCommitAttr(this.selectedCommit, 'contents').ToppingSet[toppingSlot] = diff_recipe.ToppingSet[toppingSlot];
}
}); });
} }
@ -544,6 +558,10 @@ export class MergeComponent
updateIdxList.forEach((idx) => { updateIdxList.forEach((idx) => {
this.anotherTargetRecipe[pd].recipes[idx] = commit_recipe[idx]; this.anotherTargetRecipe[pd].recipes[idx] = commit_recipe[idx];
// TODO: add topping sync, if is topping slot, set topping too! // TODO: add topping sync, if is topping slot, set topping too!
if(inRange(8111, 8130, convertFromInterProductCode(commit_recipe.recipes[idx].materialPathId))){
let toppingSlot = convertFromInterProductCode(commit_recipe.recipes[idx].materialPathId )- 8110;
this.anotherTargetRecipe[pd].ToppingSet[toppingSlot] = commit_recipe.ToppingSet[toppingSlot];
}
}); });
} }
this.recipeFromMachine = this.anotherTargetRecipe[pd]; this.recipeFromMachine = this.anotherTargetRecipe[pd];
@ -663,4 +681,12 @@ export class MergeComponent
break; break;
} }
} }
concatNoEditKeyToMap(source: any, target: any) {
for (const key of Object.keys(source)) {
if (!Object.keys(target).includes(key)) {
target[key] = source[key];
}
}
}
} }

View file

@ -221,6 +221,7 @@ export class RecipeDetailsComponent implements OnInit {
SubMenu: [...(this.rawRecipe! as any).SubMenu!], SubMenu: [...(this.rawRecipe! as any).SubMenu!],
ToppingSet: [...(this.rawRecipe as any).ToppingSet], ToppingSet: [...(this.rawRecipe as any).ToppingSet],
}; };
console.log('pre to_send', to_send);
this.concatNoEditKeyToMap(this.rawRecipe, to_send); this.concatNoEditKeyToMap(this.rawRecipe, to_send);

View file

@ -539,12 +539,15 @@ export class RecipesComponent implements OnInit, OnDestroy, AfterViewInit {
// end of Recipe Version selection // end of Recipe Version selection
openJsonTab() { async openJsonTab() {
let country = await this._recipeService.getCurrentCountry(
this.department
);
window.open( window.open(
environment.api + environment.api +
`/recipes/${this._recipeService.getCurrentCountry( `/recipes/${country}/${this._recipeService.getCurrentFile()}/json`,
this.department
)}/${this._recipeService.getCurrentFile()}/json`,
'_blank' '_blank'
); );
} }
@ -669,7 +672,7 @@ export class RecipesComponent implements OnInit, OnDestroy, AfterViewInit {
next: (data: any) => { next: (data: any) => {
if(data.status == 'OK'){ if(data.status == 'OK'){
console.log(data.result); console.log(data.result);
alert("refresh ... "); // alert("refresh ... ");
window.location.reload(); window.location.reload();
} }
} }

View file

@ -438,7 +438,7 @@ func (d *Data) GetRecipe(countryID, filename string) *models.Recipe {
} }
// cache to redis // cache to redis
d.redisClient.SetToKey(filename, recipe) err = d.redisClient.SetToKey(filename, recipe)
if err != nil { if err != nil {
d.taoLogger.Log.Error("GetRecipe: Error when read recipe file, Return default recipe", zap.Error(err)) d.taoLogger.Log.Error("GetRecipe: Error when read recipe file, Return default recipe", zap.Error(err))
@ -491,6 +491,22 @@ func (d *Data) GetRecipe(countryID, filename string) *models.Recipe {
// return d.currentRecipe // return d.currentRecipe
// } // }
func loopMatchProductCode(recipe01s []models.Recipe01, productCode string) (models.Recipe01, error) {
for _, v := range recipe01s {
if v.ProductCode == productCode {
return v, nil
} else if len(v.SubMenu) > 0 {
for _, subMenu := range v.SubMenu {
if subMenu.ProductCode == productCode {
return subMenu, nil
}
}
}
}
return models.Recipe01{}, fmt.Errorf("NotFound")
}
func (d *Data) GetRecipe01ByProductCode(filename, countryID, productCode string) (models.Recipe01, error) { func (d *Data) GetRecipe01ByProductCode(filename, countryID, productCode string) (models.Recipe01, error) {
// try convert // try convert
@ -513,33 +529,96 @@ func (d *Data) GetRecipe01ByProductCode(filename, countryID, productCode string)
// //fmt.Println("GetRecipe01ByProductCode.ReadCurrent::CurrentFile", d.CurrentFile) // //fmt.Println("GetRecipe01ByProductCode.ReadCurrent::CurrentFile", d.CurrentFile)
// //fmt.Println("GetRecipe01ByProductCode.ReadCurrent::CurrentCountryID", d.CurrentCountryID) // //fmt.Println("GetRecipe01ByProductCode.ReadCurrent::CurrentCountryID", d.CurrentCountryID)
for _, v := range d.CurrentRecipe[countryID].Recipe01 { // if redis online
if v.ProductCode == productCode { if d.redisClient.HealthCheck() == nil {
return v, nil d.taoLogger.Log.Debug("GetRecipe01ByProductCode", zap.Any("useRedis", true))
} else if len(v.SubMenu) > 0 { recipeFromRedis := d.GetRecipe(countryID, filename)
for _, subMenu := range v.SubMenu {
if subMenu.ProductCode == productCode { // find productCode from this
return subMenu, nil // for _, v := range recipeFromRedis.Recipe01 {
} // if v.ProductCode == productCode {
} // return v, nil
// } else if len(v.SubMenu) > 0 {
// for _, subMenu := range v.SubMenu {
// if subMenu.ProductCode == productCode {
// return subMenu, nil
// }
// }
// }
// }
recipe01, err := loopMatchProductCode(recipeFromRedis.Recipe01, productCode)
if err == nil {
return recipe01, nil
}
} else {
d.taoLogger.Log.Debug("GetRecipe01ByProductCode", zap.Any("useRedis", false))
// for _, v := range d.CurrentRecipe[countryID].Recipe01 {
// if v.ProductCode == productCode {
// return v, nil
// } else if len(v.SubMenu) > 0 {
// for _, subMenu := range v.SubMenu {
// if subMenu.ProductCode == productCode {
// return subMenu, nil
// }
// }
// }
// }
recipe01, err := loopMatchProductCode(d.CurrentRecipe[countryID].Recipe01, productCode)
if err == nil {
return recipe01, nil
} }
} }
// //fmt.Println("No result in current recipe", countryID) // //fmt.Println("No result in current recipe", countryID)
} else if recipe, ok := d.recipeMap[filename]; ok { } else if recipe, ok := d.recipeMap[filename]; ok {
// //fmt.Println("GetRecipe01ByProductCode.ReadMap", filename, d.CurrentFile, recipe.Recipe[countryID], "countryID=", countryID) // //fmt.Println("GetRecipe01ByProductCode.ReadMap", filename, d.CurrentFile, recipe.Recipe[countryID], "countryID=", countryID)
for _, v := range recipe.Recipe[countryID].Recipe01 { // for _, v := range recipe.Recipe[countryID].Recipe01 {
if v.ProductCode == productCode { // if v.ProductCode == productCode {
// d.taoLogger.Log.Debug("GetRecipe01ByProductCode.getSuccess", zap.Any("fromFile", filename), zap.Any("whereSource", d.recipeMap)) // // d.taoLogger.Log.Debug("GetRecipe01ByProductCode.getSuccess", zap.Any("fromFile", filename), zap.Any("whereSource", d.recipeMap))
return v, nil // return v, nil
} else if len(v.SubMenu) > 0 { // } else if len(v.SubMenu) > 0 {
for _, subMenu := range v.SubMenu { // for _, subMenu := range v.SubMenu {
if subMenu.ProductCode == productCode { // if subMenu.ProductCode == productCode {
// d.taoLogger.Log.Debug("GetRecipe01ByProductCode.getSuccess", zap.Any("fromFile", filename), zap.Any("whereSource", d.recipeMap)) // // d.taoLogger.Log.Debug("GetRecipe01ByProductCode.getSuccess", zap.Any("fromFile", filename), zap.Any("whereSource", d.recipeMap))
return subMenu, nil // return subMenu, nil
} // }
} // }
// }
// }
// if redis online
if d.redisClient.HealthCheck() == nil {
d.taoLogger.Log.Debug("GetRecipe01ByProductCode", zap.Any("useRedis", true))
recipeFromRedis := d.GetRecipe(countryID, filename)
// find productCode from this
// for _, v := range recipeFromRedis.Recipe01 {
// if v.ProductCode == productCode {
// return v, nil
// } else if len(v.SubMenu) > 0 {
// for _, subMenu := range v.SubMenu {
// if subMenu.ProductCode == productCode {
// return subMenu, nil
// }
// }
// }
// }
recipe01, err := loopMatchProductCode(recipeFromRedis.Recipe01, productCode)
if err == nil {
return recipe01, nil
}
} else {
d.taoLogger.Log.Debug("GetRecipe01ByProductCode", zap.Any("useRedis", false))
recipe01, err := loopMatchProductCode(recipe.Recipe[countryID].Recipe01, productCode)
if err == nil {
return recipe01, nil
} }
} }
d.taoLogger.Log.Debug("GetRecipe01ByProductCode.getFail", zap.Any("fromFile", filename), zap.Any("whereSource", d.recipeMap)) d.taoLogger.Log.Debug("GetRecipe01ByProductCode.getFail", zap.Any("fromFile", filename), zap.Any("whereSource", d.recipeMap))
} }
} }
@ -601,18 +680,23 @@ func (d *Data) GetRecipe01ByProductCode(filename, countryID, productCode string)
TimeStamps: time.Now().Unix(), TimeStamps: time.Now().Unix(),
} }
for _, v := range d.CurrentRecipe[countryID].Recipe01 { // for _, v := range d.CurrentRecipe[countryID].Recipe01 {
if v.ProductCode == productCode { // if v.ProductCode == productCode {
// d.taoLogger.Log.Debug("GetRecipe01ByProductCode", zap.Any("productCode", productCode), zap.Any("result", v)) // // d.taoLogger.Log.Debug("GetRecipe01ByProductCode", zap.Any("productCode", productCode), zap.Any("result", v))
return v, nil // return v, nil
} else if len(v.SubMenu) > 0 { // } else if len(v.SubMenu) > 0 {
for _, subMenu := range v.SubMenu { // for _, subMenu := range v.SubMenu {
if subMenu.ProductCode == productCode { // if subMenu.ProductCode == productCode {
// d.taoLogger.Log.Debug("GetRecipe01ByProductCode", zap.Any("productCode", productCode), zap.Any("result", subMenu)) // // d.taoLogger.Log.Debug("GetRecipe01ByProductCode", zap.Any("productCode", productCode), zap.Any("result", subMenu))
return subMenu, nil // return subMenu, nil
} // }
} // }
} // }
// }
recipe01, err := loopMatchProductCode(d.CurrentRecipe[countryID].Recipe01, productCode)
if err == nil {
return recipe01, nil
} }
return models.Recipe01{}, fmt.Errorf("product code: %s not found", productCode) return models.Recipe01{}, fmt.Errorf("product code: %s not found", productCode)
@ -1281,12 +1365,20 @@ func (d *Data) Merge(country string, filename string, attr string, changeKey str
return "UpdatedValueError", fmt.Errorf("updated value is nil") return "UpdatedValueError", fmt.Errorf("updated value is nil")
} }
// type assertion var updateRecipe01 models.Recipe01
updatedModel, ok := updated.(models.Recipe01) updatedRecord, _ := json.Marshal(updated)
d.taoLogger.Log.Debug("check on update model", zap.Any("appliedFromClient", updatedModel)) json.Unmarshal(updatedRecord, &updateRecipe01)
if !ok {
return d.MergeRecipeNoCache(country, filename, updatedModel) return d.MergeRecipeNoCache(country, filename, updateRecipe01)
}
// // updatedModel, ok := updateRecipe01.(models.Recipe01)
// // d.taoLogger.Log.Debug("check on update model", zap.Any("ok?", ok), zap.Any("appliedFromClient", updatedModel))
// if ok {
// return d.MergeRecipeNoCache(country, filename, updatedModel)
// } else {
// d.taoLogger.Log.Debug("Merge", zap.Any("targetAssertionFail", updated))
// return "Fail to upgrade: NotMatchedByType", nil
// }
} }
@ -1332,20 +1424,23 @@ func (d *Data) MergeRecipe(country, filename, changeKey string) (string, error)
// check address // check address
fmt.Println("[Source] source === recipe? ", sourceRecipe == d.GetRecipe(country, filename)) fmt.Println("[Source] source === recipe? ", sourceRecipe == d.GetRecipe(country, filename))
// apply value to its source copyOfSourceRecipe := sourceRecipe
d.SetValuesToRecipe(sourceRecipe.Recipe01, patchValue)
return d.finalizedVersion(country, sourceRecipe) // apply value to its source
d.SetValuesToRecipe(copyOfSourceRecipe.Recipe01, patchValue)
return d.finalizedVersion(country, copyOfSourceRecipe)
} }
func (d *Data) MergeRecipeNoCache(country string, filename string, updatedRecipe models.Recipe01) (string, error) { func (d *Data) MergeRecipeNoCache(country string, filename string, updatedRecipe models.Recipe01) (string, error) {
// get recipe // get recipe
sourceRecipe := d.GetRecipe(country, filename) sourceRecipe := d.GetRecipe(country, filename)
copyOfSourceRecipe := sourceRecipe
// apply value to its source // apply value to its source
d.SetValuesToRecipe(sourceRecipe.Recipe01, updatedRecipe) d.SetValuesToRecipe(copyOfSourceRecipe.Recipe01, updatedRecipe)
return d.finalizedVersion(country, sourceRecipe) return d.finalizedVersion(country, copyOfSourceRecipe)
} }
func (d *Data) finalizedVersion(country string, sourceRecipe *models.Recipe) (string, error) { func (d *Data) finalizedVersion(country string, sourceRecipe *models.Recipe) (string, error) {

View file

@ -470,7 +470,7 @@ func (rr *RecipeRouter) updateRecipe(w http.ResponseWriter, r *http.Request) {
// target saved filename // target saved filename
saved_filename := path.Join("./cofffeemachineConfig", countryID, filename) saved_filename := path.Join("./cofffeemachineConfig", countryID, filename)
// store @ temporary file // store @ temporary filex
temp_file_name := helpers.GetTempFile(saved_filename, editor, 0) temp_file_name := helpers.GetTempFile(saved_filename, editor, 0)
// push this change, editor, commit_msg into db // push this change, editor, commit_msg into db
@ -492,6 +492,13 @@ func (rr *RecipeRouter) updateRecipe(w http.ResponseWriter, r *http.Request) {
// ------------------------ SKIP THIS ------------------------ // ------------------------ SKIP THIS ------------------------
// save only changes. // save only changes.
// get new change
// newChangeRecipe, err := rr.data.GetRecipe01ByProductCode(filename, countryID, changes.ProductCode)
// if err != nil {
// // error missing
// rr.taoLogger.Log.Debug("RecipeRouter.UpdateRecipe.MissingNewChange", zap.Any("error", err))
// }
// get new tempfile name if redis is connected; // get new tempfile name if redis is connected;
productCodeNoSpl := strings.ReplaceAll(changes.ProductCode, "-", "") productCodeNoSpl := strings.ReplaceAll(changes.ProductCode, "-", "")