feat(merge_component): ✨ Add merge from website
Merge contents from patch selected by user into newer version merge from client feature
This commit is contained in:
parent
292c7697a4
commit
09c21301d6
15 changed files with 343 additions and 42 deletions
|
|
@ -114,7 +114,7 @@ export class DepartmentComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
onClick(id: string) {
|
onClick(id: string) {
|
||||||
// TODO: add handler for redirect
|
// add handler for redirect
|
||||||
this.notfoundHandler.handleSwitchCountry(id, async () => {
|
this.notfoundHandler.handleSwitchCountry(id, async () => {
|
||||||
// set country
|
// set country
|
||||||
await AsyncStorage.setItem('currentRecipeCountry', getCountryMapSwitcher(id));
|
await AsyncStorage.setItem('currentRecipeCountry', getCountryMapSwitcher(id));
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,7 @@ export class LayoutComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||||
// this.isCommitLoaded = Promise.resolve(true);
|
// this.isCommitLoaded = Promise.resolve(true);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// // TODO: optimize
|
// // optimize
|
||||||
// if(data != undefined && typeof data === 'object'){
|
// if(data != undefined && typeof data === 'object'){
|
||||||
// // check if attr exists
|
// // check if attr exists
|
||||||
// if(data.files != null && data.files != undefined){
|
// if(data.files != null && data.files != undefined){
|
||||||
|
|
|
||||||
|
|
@ -136,7 +136,7 @@ export class RecipeService {
|
||||||
}
|
}
|
||||||
|
|
||||||
getCurrentFile(): string {
|
getCurrentFile(): string {
|
||||||
// TODO: get default from server
|
// get default from server
|
||||||
|
|
||||||
const currentRecipeFile = localStorage.getItem('currentRecipeFile');
|
const currentRecipeFile = localStorage.getItem('currentRecipeFile');
|
||||||
if (currentRecipeFile) {
|
if (currentRecipeFile) {
|
||||||
|
|
@ -236,6 +236,17 @@ export class RecipeService {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
upgradeRecipe(country: string, filename: string, ctx: any){
|
||||||
|
return this._httpClient.post<any>(
|
||||||
|
environment.api + ('/recipes/upgrade/' + country + '/' + filename),
|
||||||
|
ctx,
|
||||||
|
{
|
||||||
|
withCredentials: true,
|
||||||
|
responseType: 'json',
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
getSavedTmp(country: string, filename: string) {
|
getSavedTmp(country: string, filename: string) {
|
||||||
console.log('loading saved .tmp* file', country, filename);
|
console.log('loading saved .tmp* file', country, filename);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ export class ChangelogComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
public fetchLoglist(): string[] {
|
public fetchLoglist(): string[] {
|
||||||
// TODO: Fetch changelog.html
|
// Fetch changelog.html
|
||||||
// fetch("/changelog")
|
// fetch("/changelog")
|
||||||
let dirlist: any[] = [];
|
let dirlist: any[] = [];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@
|
||||||
<div *ngIf="currentMaterialSettings != null" [formGroup]="materialSettingForm">
|
<div *ngIf="currentMaterialSettings != null" [formGroup]="materialSettingForm">
|
||||||
<p>Material Settings</p>
|
<p>Material Settings</p>
|
||||||
|
|
||||||
<!-- TODO: add form -->
|
<!-- add form -->
|
||||||
|
|
||||||
<div class="divider"></div>
|
<div class="divider"></div>
|
||||||
<div formArrayName="materialSetting" *ngFor="let material of materialSetting.controls; let i = index">
|
<div formArrayName="materialSetting" *ngFor="let material of materialSetting.controls; let i = index">
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,14 @@
|
||||||
|
|
||||||
<!-- enable from console -->
|
<!-- enable from console -->
|
||||||
<button class="hidden" (click)="testLoadCheck()">Test load</button>
|
<button class="hidden" (click)="testLoadCheck()">Test load</button>
|
||||||
|
|
||||||
|
<!-- This do send to server that the shown commit id will 1be applied to main recipe -->
|
||||||
|
|
||||||
|
<div class="m-2 space-x-2" *ngIf="selectedCommit != '' && selectedCommit != '---'">
|
||||||
|
<button class="btn btn-primary" (click)="sendApply()">Apply</button>
|
||||||
|
<button class="btn btn-error">Reject</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 3 columns with master at center -->
|
<!-- 3 columns with master at center -->
|
||||||
|
|
|
||||||
|
|
@ -70,8 +70,8 @@ export class MergeComponent implements OnInit, AfterViewInit, OnDestroy, OnChang
|
||||||
|
|
||||||
// -------------------- current selection
|
// -------------------- current selection
|
||||||
|
|
||||||
currentTargetOfMaster: any = undefined;
|
// currentTargetOfMaster: any = undefined;
|
||||||
highlightChanges: any = {};
|
// highlightChanges: any = {};
|
||||||
selectedProductCode = '';
|
selectedProductCode = '';
|
||||||
|
|
||||||
changePackage:
|
changePackage:
|
||||||
|
|
@ -97,11 +97,12 @@ export class MergeComponent implements OnInit, AfterViewInit, OnDestroy, OnChang
|
||||||
@ViewChild('templateRecipeChangeContent')
|
@ViewChild('templateRecipeChangeContent')
|
||||||
templateRecipeChangeContent!: TemplateRef<any>;
|
templateRecipeChangeContent!: TemplateRef<any>;
|
||||||
|
|
||||||
|
// ---------------------- Recipe from machine
|
||||||
|
recipeFromMachine: any = {};
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private _recipeService: RecipeService,
|
private _recipeService: RecipeService
|
||||||
private _containerRef: ViewContainerRef // private cfr: ComponentFactoryResolver,
|
)
|
||||||
) // private appRef: ApplicationRef,
|
|
||||||
// private injector: Injector
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
async ngOnChanges(changes: SimpleChanges): Promise<void> {
|
async ngOnChanges(changes: SimpleChanges): Promise<void> {
|
||||||
|
|
@ -242,6 +243,10 @@ export class MergeComponent implements OnInit, AfterViewInit, OnDestroy, OnChang
|
||||||
this.selectedCommit = commit.target.value;
|
this.selectedCommit = commit.target.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
selectAnotherSource = (sourceType: string) => {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
buildContext = () => {
|
buildContext = () => {
|
||||||
|
|
||||||
if(this.selectedCommit == "" || this.selectedCommit == undefined || this.selectedCommit == '---'){
|
if(this.selectedCommit == "" || this.selectedCommit == undefined || this.selectedCommit == '---'){
|
||||||
|
|
@ -377,4 +382,33 @@ export class MergeComponent implements OnInit, AfterViewInit, OnDestroy, OnChang
|
||||||
// getProductCodeByCommitRef = (commitRef: string) => {
|
// getProductCodeByCommitRef = (commitRef: string) => {
|
||||||
// return this.patchMap[commitRef].productCode;
|
// return this.patchMap[commitRef].productCode;
|
||||||
// };
|
// };
|
||||||
|
|
||||||
|
// use with 'apply' button
|
||||||
|
async sendApply() {
|
||||||
|
|
||||||
|
console.log("test send apply", this.fullPatches[this.selectedCommit])
|
||||||
|
|
||||||
|
let commitKey = this.getCommitAttr(this.selectedCommit, 'Change_file');
|
||||||
|
|
||||||
|
let to_send: any = {
|
||||||
|
changeKey: commitKey
|
||||||
|
}
|
||||||
|
|
||||||
|
// add appliedMachineRecipe if this is 3 ways merge
|
||||||
|
if(Object.keys(this.recipeFromMachine).length > 0){
|
||||||
|
to_send["appliedMachineRecipe"] = this.recipeFromMachine;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("sending upgrade", to_send);
|
||||||
|
|
||||||
|
this._recipeService.upgradeRecipe(
|
||||||
|
await this._recipeService.getCurrentCountry(),
|
||||||
|
this._recipeService.getCurrentFile(),
|
||||||
|
to_send
|
||||||
|
).subscribe({
|
||||||
|
next: (value) => {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -153,7 +153,7 @@
|
||||||
|
|
||||||
<!-- try pop up modal -->
|
<!-- try pop up modal -->
|
||||||
|
|
||||||
<!-- TODO: do topping -->
|
<!-- do topping -->
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="sticky bottom-0 col-span-3 max-w-screen-lg flex justify-end bg-white rounded-full drop-shadow-2xl p-3"
|
class="sticky bottom-0 col-span-3 max-w-screen-lg flex justify-end bg-white rounded-full drop-shadow-2xl p-3"
|
||||||
|
|
|
||||||
|
|
@ -144,7 +144,7 @@ export class RecipeToppingComponent implements OnInit, OnChanges {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// padding
|
// padding
|
||||||
// TODO: move padding to recipelist then insert padding between original last index and this index
|
// move padding to recipelist then insert padding between original last index and this index
|
||||||
if (this.index! > data.length) {
|
if (this.index! > data.length) {
|
||||||
// for (
|
// for (
|
||||||
// let init = this.toppingList.length - 1;
|
// let init = this.toppingList.length - 1;
|
||||||
|
|
@ -413,7 +413,7 @@ export class RecipeToppingComponent implements OnInit, OnChanges {
|
||||||
'if override',
|
'if override',
|
||||||
overrideDefault
|
overrideDefault
|
||||||
);
|
);
|
||||||
// TODO: Turn on if need to overwrite
|
// Turn on if need to overwrite
|
||||||
// value.defaultIDSelect = overrideDefault;
|
// value.defaultIDSelect = overrideDefault;
|
||||||
} else {
|
} else {
|
||||||
value.ListGroupID = [parseInt(value.groupID), 0, 0, 0];
|
value.ListGroupID = [parseInt(value.groupID), 0, 0, 0];
|
||||||
|
|
|
||||||
|
|
@ -150,7 +150,7 @@ export class RecipesComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||||
async ngOnInit(): Promise<void> {
|
async ngOnInit(): Promise<void> {
|
||||||
console.log('Trigger onInit where department = ', this.department);
|
console.log('Trigger onInit where department = ', this.department);
|
||||||
|
|
||||||
// TODO: check if department is legit
|
// check if department is legit
|
||||||
|
|
||||||
this.notfoundHandler.handleInvalidDepartment(
|
this.notfoundHandler.handleInvalidDepartment(
|
||||||
this.department!,
|
this.department!,
|
||||||
|
|
|
||||||
|
|
@ -108,7 +108,7 @@
|
||||||
</div>
|
</div>
|
||||||
</dialog>
|
</dialog>
|
||||||
|
|
||||||
<!-- TODO: save all changes and send to server -->
|
<!-- save all changes and send to server -->
|
||||||
<button class="btn">
|
<button class="btn">
|
||||||
<p>Save Changes</p>
|
<p>Save Changes</p>
|
||||||
</button>
|
</button>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package data
|
package data
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
|
@ -61,7 +62,7 @@ func NewData(taoLogger *logger.TaoLogger, redisClient *RedisCli) *Data {
|
||||||
|
|
||||||
defaultFile := "coffeethai02_600.json"
|
defaultFile := "coffeethai02_600.json"
|
||||||
|
|
||||||
// TODO: read 'version' file by country
|
// read 'version' file by country
|
||||||
|
|
||||||
// versionPath := path.Join("cofffeemachineConfig", defaultCountry, "version")
|
// versionPath := path.Join("cofffeemachineConfig", defaultCountry, "version")
|
||||||
// taoLogger.Log.Debug("version", zap.Any("version path", versionPath))
|
// taoLogger.Log.Debug("version", zap.Any("version path", versionPath))
|
||||||
|
|
@ -194,7 +195,7 @@ func (d *Data) GetRecipe(countryID, filename string) *models.Recipe {
|
||||||
|
|
||||||
d.taoLogger.Log.Debug("invoke GetRecipe", zap.String("countryID", countryID), zap.String("filename", filename))
|
d.taoLogger.Log.Debug("invoke GetRecipe", zap.String("countryID", countryID), zap.String("filename", filename))
|
||||||
|
|
||||||
// TODO: concat submenu into recipe
|
// concat submenu into recipe
|
||||||
|
|
||||||
if countryID == "" {
|
if countryID == "" {
|
||||||
d.taoLogger.Log.Debug("GetRecipe", zap.Any("EmptyCountryId", "return default country = tha"))
|
d.taoLogger.Log.Debug("GetRecipe", zap.Any("EmptyCountryId", "return default country = tha"))
|
||||||
|
|
@ -488,7 +489,7 @@ func (d *Data) SetValuesToRecipe(base_recipe []models.Recipe01, recipe models.Re
|
||||||
if v.ProductCode == recipe.ProductCode {
|
if v.ProductCode == recipe.ProductCode {
|
||||||
// Log.Debug("SetValuesToRecipe", zap.Any("old", v), zap.Any("new", recipe))
|
// Log.Debug("SetValuesToRecipe", zap.Any("old", v), zap.Any("new", recipe))
|
||||||
// v = recipe
|
// v = recipe
|
||||||
// TODO: change only changed values
|
// change only changed values
|
||||||
|
|
||||||
// transform to map
|
// transform to map
|
||||||
base_recipe01_Map := v.ToMap()
|
base_recipe01_Map := v.ToMap()
|
||||||
|
|
@ -511,7 +512,7 @@ func (d *Data) SetValuesToRecipe(base_recipe []models.Recipe01, recipe models.Re
|
||||||
if sub.ProductCode == recipe.ProductCode {
|
if sub.ProductCode == recipe.ProductCode {
|
||||||
// Log.Debug("SetValuesToRecipe.SubMenu", zap.Any("old", sub), zap.Any("new", recipe))
|
// Log.Debug("SetValuesToRecipe.SubMenu", zap.Any("old", sub), zap.Any("new", recipe))
|
||||||
// sub = recipe
|
// sub = recipe
|
||||||
// TODO: change only changed values
|
// change only changed values
|
||||||
|
|
||||||
// transform to map
|
// transform to map
|
||||||
base_recipe01_Map := sub.ToMap()
|
base_recipe01_Map := sub.ToMap()
|
||||||
|
|
@ -918,6 +919,7 @@ func (d *Data) GetCountryIDByName(countryName string) (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------ sorting ------
|
// ------ sorting ------
|
||||||
|
// FIXME: sorting not working
|
||||||
func (d *Data) SortRecipe(countryID, filename string, sort_by string) (error, []string) {
|
func (d *Data) SortRecipe(countryID, filename string, sort_by string) (error, []string) {
|
||||||
// Get recipe
|
// Get recipe
|
||||||
recipe := d.GetRecipe(countryID, filename)
|
recipe := d.GetRecipe(countryID, filename)
|
||||||
|
|
@ -1027,3 +1029,200 @@ func (d *Data) SortRecipe(countryID, filename string, sort_by string) (error, []
|
||||||
|
|
||||||
return nil, emptiedComparators
|
return nil, emptiedComparators
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// merge
|
||||||
|
|
||||||
|
func (d *Data) Merge(country string, filename string, attr string, changeKey string, updated interface{}) (string, error) {
|
||||||
|
|
||||||
|
// change this to switch case
|
||||||
|
if attr == "Recipe" {
|
||||||
|
return d.MergeRecipe(country, filename, changeKey)
|
||||||
|
} else if attr == "NoCache" {
|
||||||
|
if updated == nil {
|
||||||
|
return "UpdatedValueError", fmt.Errorf("updated value is nil")
|
||||||
|
}
|
||||||
|
return d.MergeRecipeNoCache(country, filename, updated.(models.Recipe01))
|
||||||
|
}
|
||||||
|
|
||||||
|
return "NotKnownAttr", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Data) MergeRecipe(country, filename, changeKey string) (string, error) {
|
||||||
|
// get source
|
||||||
|
prefix := "Recipe"
|
||||||
|
|
||||||
|
// read keys
|
||||||
|
keys, err := d.redisClient.KeyList()
|
||||||
|
if err != nil {
|
||||||
|
return "RedisKeysError", fmt.Errorf("error when read keys from redis: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// fullKeyString := ""
|
||||||
|
isLegit := false
|
||||||
|
// // find key that contains commitId, patchSource
|
||||||
|
for _, key := range keys {
|
||||||
|
// Recipe_<productCode>_<commitId>_<patchSource>
|
||||||
|
if strings.Contains(key, prefix) && key == changeKey {
|
||||||
|
isLegit = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !isLegit {
|
||||||
|
return "NotLegitKey", fmt.Errorf("key not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
// get actual value
|
||||||
|
patchValue := models.Recipe01{}
|
||||||
|
err = d.redisClient.GetKeyTo(changeKey, &patchValue)
|
||||||
|
if err != nil {
|
||||||
|
return "PatchValueError", fmt.Errorf("error while getting value from source: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// get recipe
|
||||||
|
sourceRecipe := d.GetRecipe(country, filename)
|
||||||
|
|
||||||
|
// apply value to its source
|
||||||
|
d.SetValuesToRecipe(sourceRecipe.Recipe01, patchValue)
|
||||||
|
// updating version
|
||||||
|
sourceRecipe.MachineSetting.ConfigNumber += 1
|
||||||
|
newVersionStr := strconv.Itoa(sourceRecipe.MachineSetting.ConfigNumber)
|
||||||
|
|
||||||
|
// save to local and redis
|
||||||
|
|
||||||
|
// create new file name
|
||||||
|
updatedFilename := ""
|
||||||
|
prefixLocalFile := "coffeethai02_"
|
||||||
|
if country != "tha" {
|
||||||
|
updatedFilename = prefixLocalFile + newVersionStr + "_" + country + ".json"
|
||||||
|
} else {
|
||||||
|
updatedFilename = prefixLocalFile + newVersionStr + ".json"
|
||||||
|
}
|
||||||
|
|
||||||
|
fullUpdatedFilename := path.Join("./cofffeemachineConfig", country, updatedFilename)
|
||||||
|
|
||||||
|
// create new file
|
||||||
|
|
||||||
|
// handle case if file already exists, add version by 1 then search new filename in loop
|
||||||
|
// list all files in dir
|
||||||
|
directory := path.Join("./cofffeemachineConfig", country)
|
||||||
|
files, err := os.ReadDir(directory)
|
||||||
|
if err != nil {
|
||||||
|
d.taoLogger.Log.Error("MergeRecipe: Error when read dir", zap.Error(err))
|
||||||
|
return "ReadDirError", fmt.Errorf("error when read dir: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, file := range files {
|
||||||
|
if file.Name() == updatedFilename {
|
||||||
|
// add version by 1
|
||||||
|
sourceRecipe.MachineSetting.ConfigNumber += 1
|
||||||
|
newVersionStr = strconv.Itoa(sourceRecipe.MachineSetting.ConfigNumber)
|
||||||
|
|
||||||
|
if country != "tha" {
|
||||||
|
updatedFilename = prefixLocalFile + newVersionStr + "_" + country + ".json"
|
||||||
|
} else {
|
||||||
|
updatedFilename = prefixLocalFile + newVersionStr + ".json"
|
||||||
|
}
|
||||||
|
|
||||||
|
fullUpdatedFilename = path.Join("./cofffeemachineConfig", country, updatedFilename)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
file, err := os.Create(fullUpdatedFilename)
|
||||||
|
if err != nil {
|
||||||
|
d.taoLogger.Log.Error("MergeRecipe: Error when create new file", zap.Error(err))
|
||||||
|
return "CreateFileError", fmt.Errorf("error when create new file: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// write file
|
||||||
|
encoder := json.NewEncoder(file)
|
||||||
|
encoder.SetIndent("", " ")
|
||||||
|
err = encoder.Encode(sourceRecipe)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
d.taoLogger.Log.Error("MergeRecipe: Error when write file", zap.Error(err))
|
||||||
|
return "WriteFileError", fmt.Errorf("error when write file: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// set cache
|
||||||
|
err = d.redisClient.SetToKey(updatedFilename, sourceRecipe)
|
||||||
|
if err != nil {
|
||||||
|
d.taoLogger.Log.Error("MergeRecipe: Error when set cache", zap.Error(err))
|
||||||
|
return "SetCacheError", fmt.Errorf("error when set cache: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return updatedFilename, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Data) MergeRecipeNoCache(country string, filename string, updatedRecipe models.Recipe01) (string, error) {
|
||||||
|
// get recipe
|
||||||
|
sourceRecipe := d.GetRecipe(country, filename)
|
||||||
|
|
||||||
|
// apply value to its source
|
||||||
|
d.SetValuesToRecipe(sourceRecipe.Recipe01, updatedRecipe)
|
||||||
|
// updating version
|
||||||
|
sourceRecipe.MachineSetting.ConfigNumber += 1
|
||||||
|
newVersionStr := strconv.Itoa(sourceRecipe.MachineSetting.ConfigNumber)
|
||||||
|
|
||||||
|
// create new file name
|
||||||
|
updatedFilename := ""
|
||||||
|
prefixLocalFile := "coffeethai02_"
|
||||||
|
if country != "tha" {
|
||||||
|
updatedFilename = prefixLocalFile + newVersionStr + "_" + country + ".json"
|
||||||
|
} else {
|
||||||
|
updatedFilename = prefixLocalFile + newVersionStr + ".json"
|
||||||
|
}
|
||||||
|
|
||||||
|
fullUpdatedFilename := path.Join("./cofffeemachineConfig", country, updatedFilename)
|
||||||
|
|
||||||
|
// create new file
|
||||||
|
|
||||||
|
// handle case if file already exists, add version by 1 then search new filename in loop
|
||||||
|
// list all files in dir
|
||||||
|
directory := path.Join("./cofffeemachineConfig", country)
|
||||||
|
files, err := os.ReadDir(directory)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
d.taoLogger.Log.Error("MergeRecipeNoCache: Error when read dir", zap.Error(err))
|
||||||
|
return "ReadDirError", fmt.Errorf("error when read dir: %v", err)
|
||||||
|
}
|
||||||
|
for _, file := range files {
|
||||||
|
if file.Name() == updatedFilename {
|
||||||
|
// add version by 1
|
||||||
|
sourceRecipe.MachineSetting.ConfigNumber += 1
|
||||||
|
newVersionStr = strconv.Itoa(sourceRecipe.MachineSetting.ConfigNumber)
|
||||||
|
|
||||||
|
if country != "tha" {
|
||||||
|
updatedFilename = prefixLocalFile + newVersionStr + "_" + country + ".json"
|
||||||
|
} else {
|
||||||
|
updatedFilename = prefixLocalFile + newVersionStr + ".json"
|
||||||
|
}
|
||||||
|
|
||||||
|
fullUpdatedFilename = path.Join("./cofffeemachineConfig", country, updatedFilename)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
file, err := os.Create(fullUpdatedFilename)
|
||||||
|
if err != nil {
|
||||||
|
d.taoLogger.Log.Error("MergeRecipeNoCache: Error when create new file", zap.Error(err))
|
||||||
|
return "CreateFileError", fmt.Errorf("error when create new file: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// write file
|
||||||
|
encoder := json.NewEncoder(file)
|
||||||
|
encoder.SetIndent("", " ")
|
||||||
|
err = encoder.Encode(sourceRecipe)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
d.taoLogger.Log.Error("MergeRecipeNoCache: Error when write file", zap.Error(err))
|
||||||
|
return "WriteFileError", fmt.Errorf("error when write file: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// set cache
|
||||||
|
err = d.redisClient.SetToKey(updatedFilename, sourceRecipe)
|
||||||
|
if err != nil {
|
||||||
|
d.taoLogger.Log.Error("MergeRecipeNoCache: Error when set cache", zap.Error(err))
|
||||||
|
return "SetCacheError", fmt.Errorf("error when set cache: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return updatedFilename, nil
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -137,7 +137,7 @@ func GetTempFile(filename string, user string, suffix int) string {
|
||||||
// return
|
// return
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// // TODO: must check the changes
|
// // must check the changes
|
||||||
|
|
||||||
// for _, file := range files {
|
// for _, file := range files {
|
||||||
// var tmpdata models.Recipe
|
// var tmpdata models.Recipe
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ func main() {
|
||||||
config, err := loadConfig(".")
|
config, err := loadConfig(".")
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO: use default config instead
|
// use default config instead
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -154,8 +154,6 @@ func (rr *RecipeRouter) Route(r chi.Router) {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
r.Post("/merge", rr.doMergeJson)
|
|
||||||
|
|
||||||
r.Get("/{country}/versions", func(w http.ResponseWriter, r *http.Request) {
|
r.Get("/{country}/versions", func(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Header().Add("Content-Type", "application/json")
|
w.Header().Add("Content-Type", "application/json")
|
||||||
|
|
||||||
|
|
@ -200,6 +198,8 @@ func (rr *RecipeRouter) Route(r chi.Router) {
|
||||||
})
|
})
|
||||||
|
|
||||||
r.Post("/sort/{country}/{filename}", rr.sortRecipe)
|
r.Post("/sort/{country}/{filename}", rr.sortRecipe)
|
||||||
|
|
||||||
|
r.Post("/upgrade/{country}/{filename}", rr.upgradeVersion)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -419,7 +419,7 @@ func (rr *RecipeRouter) updateRecipe(w http.ResponseWriter, r *http.Request) {
|
||||||
changes = changes.FromMap(ch_map)
|
changes = changes.FromMap(ch_map)
|
||||||
|
|
||||||
rr.taoLogger.Log.Debug("Changes: ", zap.Any("changes", changes))
|
rr.taoLogger.Log.Debug("Changes: ", zap.Any("changes", changes))
|
||||||
// TODO: find the matched pd
|
// find the matched pd
|
||||||
_, err = rr.data.GetRecipe01ByProductCode(filename, countryID, changes.ProductCode)
|
_, err = rr.data.GetRecipe01ByProductCode(filename, countryID, changes.ProductCode)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -465,7 +465,7 @@ func (rr *RecipeRouter) updateRecipe(w http.ResponseWriter, r *http.Request) {
|
||||||
// store @ temporary file
|
// store @ temporary file
|
||||||
temp_file_name := helpers.GetTempFile(saved_filename, editor, 0)
|
temp_file_name := helpers.GetTempFile(saved_filename, editor, 0)
|
||||||
|
|
||||||
// TODO: push this change, editor, commit_msg into db
|
// push this change, editor, commit_msg into db
|
||||||
|
|
||||||
// gen hash
|
// gen hash
|
||||||
commit_hash, err := data.HashCommit(8)
|
commit_hash, err := data.HashCommit(8)
|
||||||
|
|
@ -482,7 +482,7 @@ func (rr *RecipeRouter) updateRecipe(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------ SKIP THIS ------------------------
|
// ------------------------ SKIP THIS ------------------------
|
||||||
// TODO: save only changes.
|
// save only changes.
|
||||||
|
|
||||||
// get new tempfile name if redis is connected;
|
// get new tempfile name if redis is connected;
|
||||||
|
|
||||||
|
|
@ -541,7 +541,7 @@ func (rr *RecipeRouter) updateRecipe(w http.ResponseWriter, r *http.Request) {
|
||||||
err = data.Insert(&commit)
|
err = data.Insert(&commit)
|
||||||
|
|
||||||
err = rr.cache_db.SetToKey(patchName, changes)
|
err = rr.cache_db.SetToKey(patchName, changes)
|
||||||
// TODO: ^----- change this to patch
|
// ^----- change this to patch
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rr.taoLogger.Log.Error("RecipeRouter.UpdateRecipeCache", zap.Error(errors.WithMessage(err, "Error when write file")))
|
rr.taoLogger.Log.Error("RecipeRouter.UpdateRecipeCache", zap.Error(errors.WithMessage(err, "Error when write file")))
|
||||||
|
|
@ -580,7 +580,7 @@ func (rr *RecipeRouter) updateMaterialSetting(w http.ResponseWriter, r *http.Req
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: create commit and set change
|
// create commit and set change
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -802,18 +802,6 @@ func (rr *RecipeRouter) getImageOfProductCode(w http.ResponseWriter, r *http.Req
|
||||||
png.Encode(w, thisImage)
|
png.Encode(w, thisImage)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rr *RecipeRouter) doMergeJson(w http.ResponseWriter, r *http.Request) {
|
|
||||||
// TODO: v2, change to binary instead
|
|
||||||
if !APIhandler(w, r) {
|
|
||||||
rr.taoLogger.Log.Warn("RecipeRouter.doMergeJson", zap.Error(errors.New("API is busy")))
|
|
||||||
return
|
|
||||||
} else {
|
|
||||||
rr.taoLogger.Log.Debug("RecipeRouter.doMergeJson", zap.Any("status", "ready"))
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: add binary command here
|
|
||||||
}
|
|
||||||
|
|
||||||
func APIhandler(w http.ResponseWriter, r *http.Request) bool {
|
func APIhandler(w http.ResponseWriter, r *http.Request) bool {
|
||||||
timeout := 10 * time.Second
|
timeout := 10 * time.Second
|
||||||
|
|
||||||
|
|
@ -839,7 +827,8 @@ func lockThenTimeout(mutex *sync.Mutex, timeout time.Duration) bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------ Sorting ------------------
|
// ------------------ Sorting ------------------\
|
||||||
|
// FIXME: sorting not working, will look into it later.
|
||||||
func (rr *RecipeRouter) sortRecipe(w http.ResponseWriter, r *http.Request) {
|
func (rr *RecipeRouter) sortRecipe(w http.ResponseWriter, r *http.Request) {
|
||||||
country := chi.URLParam(r, "country")
|
country := chi.URLParam(r, "country")
|
||||||
filename := chi.URLParam(r, "filename")
|
filename := chi.URLParam(r, "filename")
|
||||||
|
|
@ -872,3 +861,63 @@ func (rr *RecipeRouter) sortRecipe(w http.ResponseWriter, r *http.Request) {
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: apply contents from commit given by id
|
||||||
|
// this do match at server
|
||||||
|
func (rr *RecipeRouter) upgradeVersion(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
|
country := chi.URLParam(r, "country")
|
||||||
|
filename := chi.URLParam(r, "filename")
|
||||||
|
|
||||||
|
// get short version country
|
||||||
|
countryID, err := rr.data.GetCountryIDByName(country)
|
||||||
|
if err != nil {
|
||||||
|
rr.taoLogger.Log.Error("RecipeRouter.upgradeVersion", zap.Error(err))
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// get commit id and patch source from body
|
||||||
|
var commitInfo map[string]interface{}
|
||||||
|
err = json.NewDecoder(r.Body).Decode(&commitInfo)
|
||||||
|
if err != nil {
|
||||||
|
rr.taoLogger.Log.Error("RecipeRouter.upgradeVersion", zap.Error(err))
|
||||||
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
mode := ""
|
||||||
|
|
||||||
|
rr.taoLogger.Log.Debug("RecipeRouter.upgradeVersion", zap.Any("commitInfo", commitInfo))
|
||||||
|
|
||||||
|
changeKey, ok := commitInfo["changeKey"].(string)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
rr.taoLogger.Log.Error("RecipeRouter.upgradeVersion", zap.Error(err))
|
||||||
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// optional AppliedMachineRecipe: if provided, use this instead
|
||||||
|
// this does mean recipe from machine has been applied on the client website
|
||||||
|
//
|
||||||
|
appliedMachineRecipe := commitInfo["appliedMachineRecipe"]
|
||||||
|
if appliedMachineRecipe != nil {
|
||||||
|
mode = "NoCache"
|
||||||
|
} else {
|
||||||
|
mode = "Recipe"
|
||||||
|
}
|
||||||
|
|
||||||
|
// upgrade version
|
||||||
|
// merge from website
|
||||||
|
result, err := rr.data.Merge(countryID, filename, mode, changeKey, nil)
|
||||||
|
if err != nil {
|
||||||
|
rr.taoLogger.Log.Error("RecipeRouter.upgradeVersion", zap.Error(err))
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Header().Add("Content-Type", "application/json")
|
||||||
|
json.NewEncoder(w).Encode(map[string]interface{}{
|
||||||
|
"result": result,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue