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>
<!-- 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>

View file

@ -100,6 +100,7 @@ export class LayoutComponent implements OnInit, OnDestroy {
this.isCommitLoaded = Promise.resolve(true);
}
// TODO: optimize
if(data != undefined && typeof data === 'object'){
// check if attr exists
if(data.files != null && data.files != undefined){

View file

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

View file

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

View file

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

View file

@ -284,6 +284,8 @@ export class RecipeListComponent implements OnInit, OnChanges {
let currStringParam = new StringParam(recipeDetailMat.StringParam);
let stringParamList = currStringParam.extract().as_list();
console.log("string param list", stringParamList);
let stringParamListTransform: any[] = [];
for (let param of stringParamList) {
// boolean transform
@ -1060,10 +1062,41 @@ export class RecipeListComponent implements OnInit, OnChanges {
if(this.diffChangeContext != undefined && this.diffChangeContext.toppingData != undefined){
// console.log('building context of topping',index, this.diffChangeContext.toppingData[index])
return {
enableEditInDiffMode: false,
preFetchedData: [this.diffChangeContext.toppingData[index]]
let emptyToppingTemplate = {
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">
<p class="font-semibold text-red-400">{{getIndexException()}}</p>
<br>
<p class="hidden">{{getIndexExceptionExplanation()}}</p>
<div
formArrayName="toppingList"
*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 { NgSelectModule } from '@ng-select/ng-select';
import {
@ -25,10 +33,13 @@ import { ActivatedRoute } from '@angular/router';
export class RecipeToppingComponent implements OnInit, OnChanges {
@Input() productCode: string = '';
@Input() index: number | undefined = undefined;
@Input() diffContext: {
enableEditInDiffMode: boolean;
preFetchedData: any;
} | undefined = undefined;
@Input() diffContext:
| {
errorInIndex?: any;
enableEditInDiffMode: boolean;
preFetchedData: any;
}
| undefined = undefined;
@Output() toppingSetChange = new EventEmitter<unknown[]>();
allToppings: Topping | undefined = undefined;
@ -49,7 +60,7 @@ export class RecipeToppingComponent implements OnInit, OnChanges {
private _toppingSetOriginalArray!: ToppingSet[];
extraTopping: [] = [];
extraToppingDefault: {[key: string]: string} = {};
extraToppingDefault: { [key: string]: string } = {};
// form
toppingForm = this._formBuilder.group(
@ -75,7 +86,7 @@ export class RecipeToppingComponent implements OnInit, OnChanges {
// get topping of this recipe
// is read mode?
if(this.diffContext != undefined){
if (this.diffContext != undefined) {
let toppingData = this.diffContext.preFetchedData! as Array<any>;
let readonly = this.diffContext.enableEditInDiffMode;
// suppose the topping data is array
@ -89,13 +100,16 @@ export class RecipeToppingComponent implements OnInit, OnChanges {
this.toppingList.push(
this._formBuilder.group({
isUse: {value: topping.isUse, disabled: readonly},
groupID: {value: topping.groupID, disabled: readonly},
defaultIDSelect: {value: topping.defaultIDSelect, disabled: readonly},
ListGroupID: {value: topping.ListGroupID, disabled: readonly},
isUse: { value: topping.isUse, disabled: readonly },
groupID: { value: topping.groupID, disabled: readonly },
defaultIDSelect: {
value: topping.defaultIDSelect,
disabled: readonly,
},
ListGroupID: { value: topping.ListGroupID, disabled: readonly },
})
);
});
});
} else {
// initialize toppinglist form
(
@ -106,11 +120,15 @@ export class RecipeToppingComponent implements OnInit, OnChanges {
)
).subscribe((data) => {
this._toppingSetOriginalArray = data;
console.log('ToppingSet', data, this.index, data.length >= this.index!, data[0]);
if(data[this.index!] != undefined && data[this.index!] != null){
console.log(
'ToppingSet',
data,
this.index,
data.length >= this.index!,
data[0]
);
if (data[this.index!] != undefined && data[this.index!] != null) {
this.listGroupId.push(data[this.index!].ListGroupID);
// 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
this.toppingForm.valueChanges.subscribe((value) => {this.triggerValueChange();});
this.toppingForm.valueChanges.subscribe((value) => {
this.triggerValueChange();
});
}
// apply on read mode
ngOnChanges(changes: SimpleChanges): void {
console.log('changes on topping', changes);
if(changes['preFetchedData']){
if (changes['preFetchedData']) {
let toppingSet = changes['preFetchedData'].currentValue as Array<any>;
this.toppingList.clear();
@ -178,17 +221,16 @@ export class RecipeToppingComponent implements OnInit, OnChanges {
this.toppingList.push(
this._formBuilder.group({
isUse: {value: topping.isUse, disabled: true},
groupID: {value: topping.groupID, disabled: true},
defaultIDSelect: {value: topping.defaultIDSelect, disabled: true},
ListGroupID: {value: topping.ListGroupID, disabled: true},
isUse: { value: topping.isUse, disabled: true },
groupID: { value: topping.groupID, disabled: true },
defaultIDSelect: { value: topping.defaultIDSelect, disabled: true },
ListGroupID: { value: topping.ListGroupID, disabled: true },
})
);
});
});
}
}
compareFunc = (a: any, b: any) => a.toString() === b.toString();
mapToppingListToMember = (mm: string[]) =>
@ -222,7 +264,6 @@ export class RecipeToppingComponent implements OnInit, OnChanges {
});
}
getToppingDefinitionByGroupId(groupID: any) {
let result = (this.allToppingsDefinitions as any).find(
(x: any) => x.groupId == groupID
);
@ -232,28 +273,39 @@ export class RecipeToppingComponent implements OnInit, OnChanges {
// for additional topping
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) => {
// 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);
}
});
}
syncWithExtraToppingDefault(groupId: string){
console.log("syncWithExtraToppingDefault::GetId", groupId, "default", this.extraToppingDefault);
syncWithExtraToppingDefault(groupId: string) {
console.log(
'syncWithExtraToppingDefault::GetId',
groupId,
'default',
this.extraToppingDefault
);
// sync to map
}
clearExtraTopping($event: any){
console.log("clear extra topping", $event);
clearExtraTopping($event: any) {
console.log('clear extra topping', $event);
// get index value of removing element
// let index = this.extraTopping.indexOf($event as never);
let groupId = $event;
@ -262,13 +314,17 @@ export class RecipeToppingComponent implements OnInit, OnChanges {
// clear default from extra
console.log("after clear", this.extraTopping, "default", this.extraToppingDefault);
console.log(
'after clear',
this.extraTopping,
'default',
this.extraToppingDefault
);
}
// getExtraDefault = (groupId: any) => (this.extraToppingDefault?.find((x: any) => x.groupId == groupId) as any)?.default;
triggerValueChange(){
triggerValueChange() {
console.log('triggerValueChange');
// transform data
@ -277,28 +333,28 @@ export class RecipeToppingComponent implements OnInit, OnChanges {
});
// extend lifetime of data
let newMapping = this.toppingList.value.map((value: {
isUse: boolean;
groupID: string;
defaultIDSelect: string;
ListGroupID: string[];
}) => this.transformToppingsetStructure(value));
let newMapping = this.toppingList.value.map(
(value: {
isUse: boolean;
groupID: string;
defaultIDSelect: string;
ListGroupID: string[];
}) => this.transformToppingsetStructure(value)
);
// before emit
console.log("emit", newMapping);
console.log('emit', newMapping);
// get current value of controls
this.toppingSetChange.emit([this.index! , newMapping]);
this.toppingSetChange.emit([this.index!, newMapping]);
}
// bind default back to extraTopping
bindDefaultToExtraTopping(groupId: any){
bindDefaultToExtraTopping(groupId: any) {
this.extraToppingDefault![groupId] = '0';
}
cloneValue(value: any){
cloneValue(value: any) {
console.log('cloneValue', 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) => {
if(value.defaultIDSelect == null){
if (value.defaultIDSelect == null) {
value.defaultIDSelect = 0;
} else {
value.defaultIDSelect = parseInt(value.defaultIDSelect);
}
if(!Array.isArray(value.ListGroupID)){
if (!Array.isArray(value.ListGroupID)) {
value.ListGroupID = [parseInt(value.groupID), 0, 0, 0];
}
if(value.groupID == null){
if (value.groupID == null) {
value.groupID = '0';
}
// in case of.doing mix override topping
if(this.extraTopping.length > 0){
let concatArr = [value.ListGroupID[0], ...((this.extraTopping).map((x: string) => parseInt(x)))];
if (this.extraTopping.length > 0) {
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
while (concatArr.length < value.ListGroupID.length) {
concatArr.push(0);
@ -338,17 +396,23 @@ export class RecipeToppingComponent implements OnInit, OnChanges {
// get last element that is not 0
let lastIndex = concatArr.findIndex((x: any) => x == 0) - 1;
if(lastIndex <= -1){
if (lastIndex <= -1) {
lastIndex = 0;
}
let overrideDefault = parseInt(this.extraToppingDefault![concatArr[lastIndex]]);
let overrideDefault = parseInt(
this.extraToppingDefault![concatArr[lastIndex]]
);
// 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
// value.defaultIDSelect = overrideDefault;
} else {
value.ListGroupID = [parseInt(value.groupID), 0, 0, 0];
}
@ -361,7 +425,12 @@ export class RecipeToppingComponent implements OnInit, OnChanges {
};
};
// 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,
}), zapcore.AddSync(&lumberjack.Logger{
Filename: "services/logger/serverlog.log",
MaxSize: 10, // megabytes
MaxSize: 5, // megabytes
MaxAge: 28, //days
LocalTime: true,
Compress: true,
}), enableDebugMode),
zapcore.NewCore(zapcore.NewConsoleEncoder(zapcore.EncoderConfig{
TimeKey: "timestamp",