fix(merge_component): 🚧 try fix delayed commit show

Try solving delayed commit show, WIP topping and string param display for commit modal
This commit is contained in:
pakintada@gmail.com 2024-03-02 11:15:48 +07:00
parent ce7d595427
commit 517e051f2d
9 changed files with 232 additions and 107 deletions

View file

@ -41,7 +41,7 @@
</div> </div>
<!-- File Change Status --> <!-- File Change Status -->
<button onclick="patch_merge_modal.showModal()" *ngIf="isCommitLoaded"> <button onclick="patch_merge_modal.showModal()" *ngIf="isCommitLoaded | async">
<h1 class="text-center font-extrabold text-2xl text-red-500 animate-pulse">Detect Changes! Click</h1> <h1 class="text-center font-extrabold text-2xl text-red-500 animate-pulse">Detect Changes! Click</h1>

View file

@ -100,6 +100,7 @@ export class LayoutComponent implements OnInit, OnDestroy {
this.isCommitLoaded = Promise.resolve(true); this.isCommitLoaded = Promise.resolve(true);
} }
// TODO: 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){

View file

@ -56,7 +56,7 @@
<!-- display zone --> <!-- display zone -->
<div *ngFor="let pd of getProductCodesOfCommits()"> <div *ngFor="let pd of getProductCodesOfCommits()">
<div class="container"> <div class="container" *ngIf="pd == getCommitAttr(selectedCommit, 'contents').productCode">
<details class="collapse collapse-arrow"> <details class="collapse collapse-arrow">
<summary class="collapse-title">{{ pd }}</summary> <summary class="collapse-title">{{ pd }}</summary>
<div> <div>

View file

@ -5,8 +5,10 @@ import {
ComponentFactoryResolver, ComponentFactoryResolver,
Injector, Injector,
Input, Input,
OnChanges,
OnDestroy, OnDestroy,
OnInit, OnInit,
SimpleChanges,
TemplateRef, TemplateRef,
ViewChild, ViewChild,
ViewContainerRef, ViewContainerRef,
@ -49,7 +51,7 @@ import { ResizeEvent, ResizableModule } from 'angular-resizable-element';
ResizableModule ResizableModule
], ],
}) })
export class MergeComponent implements OnInit, AfterViewInit, OnDestroy { export class MergeComponent implements OnInit, AfterViewInit, OnDestroy, OnChanges {
onRecipeListFormChange($event: any) {} onRecipeListFormChange($event: any) {}
// input from layout::getSavedTmp // input from layout::getSavedTmp
@ -102,43 +104,51 @@ export class MergeComponent implements OnInit, AfterViewInit, OnDestroy {
// private injector: Injector // private injector: Injector
{} {}
async ngOnInit(): Promise<void> { async ngOnChanges(changes: SimpleChanges): Promise<void> {
this._recipeService.getPatchListOfCurrentFile( this._recipeService.getPatchListOfCurrentFile(
await this._recipeService.getCurrentCountry(), await this._recipeService.getCurrentCountry(),
this._recipeService.getCurrentFile() this._recipeService.getCurrentFile()
) )
.subscribe({ .subscribe({
next: (data: any) => { next: (data: any) => {
this.patchMap = data; this.patchMap = data;
// console.log("patches",this.patchMap); // console.log("patches",this.patchMap);
// console.log("commits", this.commit!); // console.log("commits", this.commit!);
this.getPatchMapKeys().forEach(async (key) => { this.getPatchMapKeys().forEach(async (key) => {
this.fullPatches[key] = { this.fullPatches[key] = {
contents: this.patchMap[key], contents: this.patchMap[key],
...this.commit!.find((commit: any) => commit.Id === key), ...this.commit!.find((commit: any) => commit.Id === key),
}; };
// find product code from commits // find product code from commits
let productCode = this.patchMap[key].productCode; let productCode = this.patchMap[key].productCode;
if (productCode) { if (productCode) {
// check if exist in map // check if exist in map
if (!this.mapProductCodeWithCommits[productCode]) { if (!this.mapProductCodeWithCommits[productCode]) {
this.mapProductCodeWithCommits[productCode] = [key]; this.mapProductCodeWithCommits[productCode] = [key];
} else { } else {
this.mapProductCodeWithCommits[productCode].push(key); this.mapProductCodeWithCommits[productCode].push(key);
}
} }
}
// store only // store only
await this.getMasterRecipeOfProductCode(productCode!); await this.getMasterRecipeOfProductCode(productCode!);
// console.log("get master-commits recipe", this.mapProductCodeWithCommits); // console.log("get master-commits recipe", this.mapProductCodeWithCommits);
}); });
console.log('full patch', this.fullPatches);
// console.log('change map', this.changeMap);
},
complete: () => {
console.log("full patch on complete", this.fullPatches);
},
});
}
async ngOnInit(): Promise<void> {
console.log('full patch', this.fullPatches);
// console.log('change map', this.changeMap);
},
});
// fetch related product codes // fetch related product codes
} }
@ -244,7 +254,7 @@ export class MergeComponent implements OnInit, AfterViewInit, OnDestroy {
// console.log("read commit contents",this.getCommitAttr(this.selectedCommit, 'contents').ToppingSet); // console.log("read commit contents",this.getCommitAttr(this.selectedCommit, 'contents').ToppingSet);
let patchData = this.fullPatches[this.selectedCommit]; let patchData = this.fullPatches[this.selectedCommit];
console.log("patch data", patchData); // console.log("patch data", patchData);
// this.changePackage = { // this.changePackage = {

View file

@ -277,9 +277,11 @@ export class RecipeDetailsComponent implements OnInit {
} }
onRecipeListFormChange(repl: unknown[]) { onRecipeListFormChange(repl: unknown[]) {
// console.log('Recipe List Form Changed', repl); console.log('Recipe List Form Changed', repl);
this.repl = repl[1] as never[];
this.tpl = repl[0] as never[]; 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++) { for (let ti = 0; ti < this.tpl.length; ti++) {
// check at the same index // check at the same index
if (!isEqual(this.tpl[ti][0], (this.rawRecipe as any).ToppingSet[ti])) { if (!isEqual(this.tpl[ti][0], (this.rawRecipe as any).ToppingSet[ti])) {
@ -289,6 +291,11 @@ export class RecipeDetailsComponent implements OnInit {
this.tpl[ti][0], this.tpl[ti][0],
(this.rawRecipe as any).ToppingSet[ti] (this.rawRecipe as any).ToppingSet[ti]
); );
// check length
// update raw recipe // update raw recipe
(this.rawRecipe as any).ToppingSet[ti] = this.tpl[ti][0]; (this.rawRecipe as any).ToppingSet[ti] = this.tpl[ti][0];
console.log( console.log(

View file

@ -284,6 +284,8 @@ export class RecipeListComponent implements OnInit, OnChanges {
let currStringParam = new StringParam(recipeDetailMat.StringParam); let currStringParam = new StringParam(recipeDetailMat.StringParam);
let stringParamList = currStringParam.extract().as_list(); let stringParamList = currStringParam.extract().as_list();
console.log("string param list", stringParamList);
let stringParamListTransform: any[] = []; let stringParamListTransform: any[] = [];
for (let param of stringParamList) { for (let param of stringParamList) {
// boolean transform // boolean transform
@ -1060,10 +1062,41 @@ export class RecipeListComponent implements OnInit, OnChanges {
if(this.diffChangeContext != undefined && this.diffChangeContext.toppingData != undefined){ if(this.diffChangeContext != undefined && this.diffChangeContext.toppingData != undefined){
// console.log('building context of topping',index, this.diffChangeContext.toppingData[index]) // console.log('building context of topping',index, this.diffChangeContext.toppingData[index])
return {
enableEditInDiffMode: false, let emptyToppingTemplate = {
preFetchedData: [this.diffChangeContext.toppingData[index]] isUse: false,
groupID: 0,
defaultIDSelect: 0,
ListGroupID: ["0", "0", "0", "0"],
}; };
// check on data length
if(index > this.diffChangeContext.toppingData.length - 1){
// padding
}
let fetchedData = this.diffChangeContext.toppingData[index];
let raisedIndexException = "Index error! require ["+(index + 1).toString()+"] but data not found!";
if(fetchedData == undefined || fetchedData == null){
fetchedData = emptyToppingTemplate;
}
let context = {
errorInIndex: {
causedBy: "[ERROR?] has slot but topping data not found.",
fullExplanation: raisedIndexException + " Reached upper limit or not yet implemented. ",
},
enableEditInDiffMode: false,
preFetchedData: [fetchedData]
}
if(this.diffChangeContext.toppingData[index] != undefined || this.diffChangeContext.toppingData[index] != null || index > this.diffChangeContext.toppingData.length - 1){
context.errorInIndex.causedBy = "";
}
return context;
} }

View file

@ -1,4 +1,8 @@
<div [formGroup]="toppingForm"> <div [formGroup]="toppingForm">
<p class="font-semibold text-red-400">{{getIndexException()}}</p>
<br>
<p class="hidden">{{getIndexExceptionExplanation()}}</p>
<div <div
formArrayName="toppingList" formArrayName="toppingList"
*ngFor="let topping of toppingList.controls; let i = index" *ngFor="let topping of toppingList.controls; let i = index"

View file

@ -1,4 +1,12 @@
import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core'; import {
Component,
EventEmitter,
Input,
OnChanges,
OnInit,
Output,
SimpleChanges,
} from '@angular/core';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { NgSelectModule } from '@ng-select/ng-select'; import { NgSelectModule } from '@ng-select/ng-select';
import { import {
@ -25,10 +33,13 @@ import { ActivatedRoute } from '@angular/router';
export class RecipeToppingComponent implements OnInit, OnChanges { export class RecipeToppingComponent implements OnInit, OnChanges {
@Input() productCode: string = ''; @Input() productCode: string = '';
@Input() index: number | undefined = undefined; @Input() index: number | undefined = undefined;
@Input() diffContext: { @Input() diffContext:
enableEditInDiffMode: boolean; | {
preFetchedData: any; errorInIndex?: any;
} | undefined = undefined; enableEditInDiffMode: boolean;
preFetchedData: any;
}
| undefined = undefined;
@Output() toppingSetChange = new EventEmitter<unknown[]>(); @Output() toppingSetChange = new EventEmitter<unknown[]>();
allToppings: Topping | undefined = undefined; allToppings: Topping | undefined = undefined;
@ -49,7 +60,7 @@ export class RecipeToppingComponent implements OnInit, OnChanges {
private _toppingSetOriginalArray!: ToppingSet[]; private _toppingSetOriginalArray!: ToppingSet[];
extraTopping: [] = []; extraTopping: [] = [];
extraToppingDefault: {[key: string]: string} = {}; extraToppingDefault: { [key: string]: string } = {};
// form // form
toppingForm = this._formBuilder.group( toppingForm = this._formBuilder.group(
@ -75,7 +86,7 @@ export class RecipeToppingComponent implements OnInit, OnChanges {
// get topping of this recipe // get topping of this recipe
// is read mode? // is read mode?
if(this.diffContext != undefined){ if (this.diffContext != undefined) {
let toppingData = this.diffContext.preFetchedData! as Array<any>; let toppingData = this.diffContext.preFetchedData! as Array<any>;
let readonly = this.diffContext.enableEditInDiffMode; let readonly = this.diffContext.enableEditInDiffMode;
// suppose the topping data is array // suppose the topping data is array
@ -89,13 +100,16 @@ export class RecipeToppingComponent implements OnInit, OnChanges {
this.toppingList.push( this.toppingList.push(
this._formBuilder.group({ this._formBuilder.group({
isUse: {value: topping.isUse, disabled: readonly}, isUse: { value: topping.isUse, disabled: readonly },
groupID: {value: topping.groupID, disabled: readonly}, groupID: { value: topping.groupID, disabled: readonly },
defaultIDSelect: {value: topping.defaultIDSelect, disabled: readonly}, defaultIDSelect: {
ListGroupID: {value: topping.ListGroupID, disabled: readonly}, value: topping.defaultIDSelect,
disabled: readonly,
},
ListGroupID: { value: topping.ListGroupID, disabled: readonly },
}) })
); );
}); });
} else { } else {
// initialize toppinglist form // initialize toppinglist form
( (
@ -106,11 +120,15 @@ export class RecipeToppingComponent implements OnInit, OnChanges {
) )
).subscribe((data) => { ).subscribe((data) => {
this._toppingSetOriginalArray = data; this._toppingSetOriginalArray = data;
console.log('ToppingSet', data, this.index, data.length >= this.index!, data[0]); console.log(
'ToppingSet',
data,
if(data[this.index!] != undefined && data[this.index!] != null){ this.index,
data.length >= this.index!,
data[0]
);
if (data[this.index!] != undefined && data[this.index!] != null) {
this.listGroupId.push(data[this.index!].ListGroupID); this.listGroupId.push(data[this.index!].ListGroupID);
// check length of toppingList if in range with given index // check length of toppingList if in range with given index
@ -125,9 +143,32 @@ export class RecipeToppingComponent implements OnInit, OnChanges {
); );
} }
console.log('SubscribeToppingSet', this.toppingList, "list group id=", this.listGroupId); // padding
} if (this.index! > data.length) {
for (
let init = this.toppingList.length - 1;
this.toppingList.at(this.index!) == undefined &&
init < this.index!;
init++
) {
this.toppingList.push(
this._formBuilder.group({
isUse: false,
groupID: "0",
defaultIDSelect: 0,
ListGroupID: [0, 0, 0, 0],
})
);
}
}
console.log(
'SubscribeToppingSet',
this.toppingList,
'list group id=',
this.listGroupId
);
}
}); });
} }
@ -160,14 +201,16 @@ export class RecipeToppingComponent implements OnInit, OnChanges {
}); });
// emit value changes // emit value changes
this.toppingForm.valueChanges.subscribe((value) => {this.triggerValueChange();}); this.toppingForm.valueChanges.subscribe((value) => {
this.triggerValueChange();
});
} }
// apply on read mode // apply on read mode
ngOnChanges(changes: SimpleChanges): void { ngOnChanges(changes: SimpleChanges): void {
console.log('changes on topping', changes); console.log('changes on topping', changes);
if(changes['preFetchedData']){ if (changes['preFetchedData']) {
let toppingSet = changes['preFetchedData'].currentValue as Array<any>; let toppingSet = changes['preFetchedData'].currentValue as Array<any>;
this.toppingList.clear(); this.toppingList.clear();
@ -178,17 +221,16 @@ export class RecipeToppingComponent implements OnInit, OnChanges {
this.toppingList.push( this.toppingList.push(
this._formBuilder.group({ this._formBuilder.group({
isUse: {value: topping.isUse, disabled: true}, isUse: { value: topping.isUse, disabled: true },
groupID: {value: topping.groupID, disabled: true}, groupID: { value: topping.groupID, disabled: true },
defaultIDSelect: {value: topping.defaultIDSelect, disabled: true}, defaultIDSelect: { value: topping.defaultIDSelect, disabled: true },
ListGroupID: {value: topping.ListGroupID, disabled: true}, ListGroupID: { value: topping.ListGroupID, disabled: true },
}) })
); );
}); });
} }
} }
compareFunc = (a: any, b: any) => a.toString() === b.toString(); compareFunc = (a: any, b: any) => a.toString() === b.toString();
mapToppingListToMember = (mm: string[]) => mapToppingListToMember = (mm: string[]) =>
@ -222,7 +264,6 @@ export class RecipeToppingComponent implements OnInit, OnChanges {
}); });
} }
getToppingDefinitionByGroupId(groupID: any) { getToppingDefinitionByGroupId(groupID: any) {
let result = (this.allToppingsDefinitions as any).find( let result = (this.allToppingsDefinitions as any).find(
(x: any) => x.groupId == groupID (x: any) => x.groupId == groupID
); );
@ -232,28 +273,39 @@ export class RecipeToppingComponent implements OnInit, OnChanges {
// for additional topping // for additional topping
registerExtraTopping(event: any) { registerExtraTopping(event: any) {
console.log("get value from extra topping", this.extraTopping, "default", this.extraToppingDefault, "param event", event); console.log(
'get value from extra topping',
this.extraTopping,
'default',
this.extraToppingDefault,
'param event',
event
);
this.extraTopping.forEach((x: any) => { this.extraTopping.forEach((x: any) => {
// do check if x is registered // do check if x is registered
if(this.extraToppingDefault[x] == null || this.extraToppingDefault[x] == undefined){ if (
this.extraToppingDefault[x] == null ||
this.extraToppingDefault[x] == undefined
) {
this.bindDefaultToExtraTopping(x); this.bindDefaultToExtraTopping(x);
} }
}); });
} }
syncWithExtraToppingDefault(groupId: string){ syncWithExtraToppingDefault(groupId: string) {
console.log("syncWithExtraToppingDefault::GetId", groupId, "default", this.extraToppingDefault); console.log(
'syncWithExtraToppingDefault::GetId',
groupId,
'default',
this.extraToppingDefault
);
// sync to map // sync to map
} }
clearExtraTopping($event: any){ clearExtraTopping($event: any) {
console.log("clear extra topping", $event); console.log('clear extra topping', $event);
// get index value of removing element // get index value of removing element
// let index = this.extraTopping.indexOf($event as never); // let index = this.extraTopping.indexOf($event as never);
let groupId = $event; let groupId = $event;
@ -262,13 +314,17 @@ export class RecipeToppingComponent implements OnInit, OnChanges {
// clear default from extra // clear default from extra
console.log(
console.log("after clear", this.extraTopping, "default", this.extraToppingDefault); 'after clear',
this.extraTopping,
'default',
this.extraToppingDefault
);
} }
// getExtraDefault = (groupId: any) => (this.extraToppingDefault?.find((x: any) => x.groupId == groupId) as any)?.default; // getExtraDefault = (groupId: any) => (this.extraToppingDefault?.find((x: any) => x.groupId == groupId) as any)?.default;
triggerValueChange(){ triggerValueChange() {
console.log('triggerValueChange'); console.log('triggerValueChange');
// transform data // transform data
@ -277,28 +333,28 @@ export class RecipeToppingComponent implements OnInit, OnChanges {
}); });
// extend lifetime of data // extend lifetime of data
let newMapping = this.toppingList.value.map((value: { let newMapping = this.toppingList.value.map(
isUse: boolean; (value: {
groupID: string; isUse: boolean;
defaultIDSelect: string; groupID: string;
ListGroupID: string[]; defaultIDSelect: string;
}) => this.transformToppingsetStructure(value)); ListGroupID: string[];
}) => this.transformToppingsetStructure(value)
);
// before emit // before emit
console.log("emit", newMapping); console.log('emit', newMapping);
// get current value of controls // get current value of controls
this.toppingSetChange.emit([this.index! , newMapping]); this.toppingSetChange.emit([this.index!, newMapping]);
} }
// bind default back to extraTopping // bind default back to extraTopping
bindDefaultToExtraTopping(groupId: any){ bindDefaultToExtraTopping(groupId: any) {
this.extraToppingDefault![groupId] = '0'; this.extraToppingDefault![groupId] = '0';
} }
cloneValue(value: any){ cloneValue(value: any) {
console.log('cloneValue', value); console.log('cloneValue', value);
// return a clone value that not address to the original value // return a clone value that not address to the original value
@ -306,26 +362,28 @@ export class RecipeToppingComponent implements OnInit, OnChanges {
} }
transformToppingsetStructure = (value: any) => { transformToppingsetStructure = (value: any) => {
if (value.defaultIDSelect == null) {
if(value.defaultIDSelect == null){
value.defaultIDSelect = 0; value.defaultIDSelect = 0;
} else { } else {
value.defaultIDSelect = parseInt(value.defaultIDSelect); value.defaultIDSelect = parseInt(value.defaultIDSelect);
} }
if(!Array.isArray(value.ListGroupID)){ if (!Array.isArray(value.ListGroupID)) {
value.ListGroupID = [parseInt(value.groupID), 0, 0, 0]; value.ListGroupID = [parseInt(value.groupID), 0, 0, 0];
} }
if(value.groupID == null){ if (value.groupID == null) {
value.groupID = '0'; value.groupID = '0';
} }
// in case of.doing mix override topping // in case of.doing mix override topping
if(this.extraTopping.length > 0){ if (this.extraTopping.length > 0) {
let concatArr = [value.ListGroupID[0], ...((this.extraTopping).map((x: string) => parseInt(x)))]; let concatArr = [
value.ListGroupID[0],
...this.extraTopping.map((x: string) => parseInt(x)),
];
if(concatArr.length < value.ListGroupID.length){ if (concatArr.length < value.ListGroupID.length) {
// fill with 0 // fill with 0
while (concatArr.length < value.ListGroupID.length) { while (concatArr.length < value.ListGroupID.length) {
concatArr.push(0); concatArr.push(0);
@ -338,17 +396,23 @@ export class RecipeToppingComponent implements OnInit, OnChanges {
// get last element that is not 0 // get last element that is not 0
let lastIndex = concatArr.findIndex((x: any) => x == 0) - 1; let lastIndex = concatArr.findIndex((x: any) => x == 0) - 1;
if(lastIndex <= -1){ if (lastIndex <= -1) {
lastIndex = 0; lastIndex = 0;
} }
let overrideDefault = parseInt(this.extraToppingDefault![concatArr[lastIndex]]); let overrideDefault = parseInt(
this.extraToppingDefault![concatArr[lastIndex]]
);
// value.defaultIDSelect = parseInt(this.extraToppingDefault![value.groupID]); // value.defaultIDSelect = parseInt(this.extraToppingDefault![value.groupID]);
console.log("value.defaultIDSelect", value.defaultIDSelect, "if override", overrideDefault); console.log(
'value.defaultIDSelect',
value.defaultIDSelect,
'if override',
overrideDefault
);
// TODO: Turn on if need to overwrite // TODO: 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];
} }
@ -361,7 +425,12 @@ export class RecipeToppingComponent implements OnInit, OnChanges {
}; };
}; };
// read only mode // read only mode
isReadonly = () => this.diffContext != undefined && this.diffContext.enableEditInDiffMode; isReadonly = () =>
this.diffContext != undefined && this.diffContext.enableEditInDiffMode;
// bug check
getIndexException = () => this.diffContext?.errorInIndex!.causedBy;
getIndexExceptionExplanation = () =>
this.diffContext?.errorInIndex!.fullExplanation;
} }

View file

@ -33,9 +33,10 @@ func (tl *TaoLogger) initConfig() *zap.Logger {
EncodeTime: zapcore.ISO8601TimeEncoder, EncodeTime: zapcore.ISO8601TimeEncoder,
}), zapcore.AddSync(&lumberjack.Logger{ }), zapcore.AddSync(&lumberjack.Logger{
Filename: "services/logger/serverlog.log", Filename: "services/logger/serverlog.log",
MaxSize: 10, // megabytes MaxSize: 5, // megabytes
MaxAge: 28, //days MaxAge: 28, //days
LocalTime: true, LocalTime: true,
Compress: true,
}), enableDebugMode), }), enableDebugMode),
zapcore.NewCore(zapcore.NewConsoleEncoder(zapcore.EncoderConfig{ zapcore.NewCore(zapcore.NewConsoleEncoder(zapcore.EncoderConfig{
TimeKey: "timestamp", TimeKey: "timestamp",