add deepCompare for merge, WIP merge
This commit is contained in:
parent
ed7810cded
commit
cf5b11b267
6 changed files with 234 additions and 19 deletions
|
|
@ -41,11 +41,26 @@
|
|||
</div>
|
||||
|
||||
<!-- File Change Status -->
|
||||
<button *ngIf="showDetectChanges">
|
||||
<button onclick="patch_merge_modal.showModal()" *ngIf="showDetectChanges">
|
||||
|
||||
<h1 class="text-center font-extrabold text-2xl text-red-500 animate-pulse">Detect Changes! Click</h1>
|
||||
|
||||
</button>
|
||||
<dialog id="patch_merge_modal" class="modal">
|
||||
|
||||
<div class="modal-box max-w-screen-2xl">
|
||||
<app-merge
|
||||
[commit]="changesCommit"
|
||||
></app-merge>
|
||||
<div class="modal-action sticky bottom-0 right-0">
|
||||
<form method="dialog">
|
||||
<button class="btn btn-warning">Close</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</dialog>
|
||||
|
||||
<div class="flex items-center">
|
||||
<div class="flex items-center ml-3">
|
||||
|
|
@ -168,4 +183,3 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!--Modal-->
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ export class LayoutComponent implements OnInit, OnDestroy {
|
|||
|
||||
redisStatus:string = "Offline";
|
||||
showDetectChanges: boolean = false;
|
||||
changesCommit: any = undefined;
|
||||
|
||||
constructor(
|
||||
private _userService: UserService,
|
||||
|
|
@ -94,9 +95,11 @@ export class LayoutComponent implements OnInit, OnDestroy {
|
|||
next: async (data: any) => {
|
||||
if(data != undefined && typeof data === 'object'){
|
||||
// check if attr exists
|
||||
if(data.files != null){
|
||||
if(data.files != null && data.files != undefined){
|
||||
this.showDetectChanges = true;
|
||||
await AsyncStorage.setItem("detectChanges", "true");
|
||||
this.changesCommit = data.files;
|
||||
console.log("get commits", this.changesCommit);
|
||||
} else {
|
||||
this.showDetectChanges = false;
|
||||
await AsyncStorage.setItem("detectChanges", "false");
|
||||
|
|
|
|||
|
|
@ -1 +1,40 @@
|
|||
<p>merge works!</p>
|
||||
<!-- 3 columns with master at center -->
|
||||
<div class="grid grid-cols-3">
|
||||
<!-- from patch -->
|
||||
<div>
|
||||
<div class="m-2" *ngFor="let patchKey of getPatchMapKeys()">
|
||||
|
||||
|
||||
|
||||
<mat-card class="!bg-amber-300 !rounded-xl p-2">
|
||||
<mat-card-title>
|
||||
{{getCommitAttr(patchKey, 'Msg')}}
|
||||
</mat-card-title>
|
||||
<mat-card-content>
|
||||
<div>
|
||||
<p>date: {{getCommitAttr(patchKey, 'Created_at') }}</p>
|
||||
<p>editor: {{getCommitAttr(patchKey, 'Editor') }}</p>
|
||||
<p>ref: {{patchKey}}</p>
|
||||
|
||||
<p class="hidden">full ref: {{getCommitAttr(patchKey, 'Change_file')}}</p>
|
||||
|
||||
<button mat-raised-button class="!bg-white" (click)="copyRef(getCommitAttr(patchKey, 'Change_file'))">Copy full ref</button>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- from master -->
|
||||
<div>
|
||||
<p>master</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- from machine -->
|
||||
<div>
|
||||
<p>machine</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,31 +1,117 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { RecipeService } from 'src/app/core/services/recipe.service';
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { copy } from 'src/app/shared/helpers/copy';
|
||||
import { compare } from 'src/app/shared/helpers/compare';
|
||||
import { AsyncStorage } from 'src/app/shared/helpers/asyncStorage';
|
||||
|
||||
@Component({
|
||||
selector: 'app-merge',
|
||||
standalone: true,
|
||||
imports: [CommonModule],
|
||||
imports: [CommonModule, MatCardModule, MatButtonModule],
|
||||
templateUrl: './merge.component.html',
|
||||
})
|
||||
export class MergeComponent implements OnInit {
|
||||
@Input() commit: Array<any> | undefined = undefined;
|
||||
|
||||
patchMap: any = {}
|
||||
patchMap: any = {};
|
||||
fullPatches: any = {};
|
||||
conflictList: string[] = [];
|
||||
|
||||
constructor(
|
||||
private _recipeService: RecipeService
|
||||
) { }
|
||||
//map productCode:commits
|
||||
mapProductCodeWithCommits: any = {};
|
||||
// master recipes for product code given by commits
|
||||
targetRecipe: any = {}
|
||||
// change map
|
||||
changeMap: any = {};
|
||||
|
||||
constructor(private _recipeService: RecipeService) {}
|
||||
|
||||
async ngOnInit(): Promise<void> {
|
||||
(await this._recipeService.getPatchListOfCurrentFile(
|
||||
await this._recipeService.getCurrentCountry(),
|
||||
this._recipeService.getCurrentFile()
|
||||
)).subscribe({
|
||||
(
|
||||
await this._recipeService.getPatchListOfCurrentFile(
|
||||
await this._recipeService.getCurrentCountry(),
|
||||
this._recipeService.getCurrentFile()
|
||||
)
|
||||
).subscribe({
|
||||
next: (data: any) => {
|
||||
this.patchMap = data;
|
||||
console.log("patches",this.patchMap);
|
||||
}
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
// store only
|
||||
await this.getMasterRecipeOfProductCode(productCode!);
|
||||
|
||||
// console.log("get master-commits recipe", this.mapProductCodeWithCommits);
|
||||
});
|
||||
|
||||
console.log('full patch', this.fullPatches);
|
||||
// console.log('change map', this.changeMap);
|
||||
},
|
||||
});
|
||||
|
||||
// fetch related product codes
|
||||
|
||||
}
|
||||
|
||||
// funcitons
|
||||
|
||||
// get patch map keys
|
||||
getPatchMapKeys = () => Object.keys(this.patchMap);
|
||||
|
||||
// get commit message by commit id
|
||||
getCommitAttr = (id: string, attr: string) => this.fullPatches[id][attr];
|
||||
|
||||
// copy to clipboard
|
||||
copyRef = async (ref: string) => await copy(ref);
|
||||
|
||||
|
||||
// ----------------------------- Master Functions ---------------------------
|
||||
getMasterRecipeOfProductCode = async (productCode: string) => {
|
||||
(await this._recipeService.getRawRecipeOfProductCode(
|
||||
await this._recipeService.getCurrentCountry(),
|
||||
this._recipeService.getCurrentFile(),
|
||||
productCode
|
||||
)).subscribe({
|
||||
next: (data: any) => {
|
||||
this.targetRecipe[productCode] = data;
|
||||
// console.log("get master recipe", this.targetRecipe);
|
||||
|
||||
// for each patch, get diff master <---> patch
|
||||
// test compare
|
||||
this.getPatchMapKeys().forEach((patchId) => {
|
||||
// compare with master
|
||||
let cmp = compare(
|
||||
this.targetRecipe[productCode!],
|
||||
this.fullPatches[patchId].contents,
|
||||
['LastChange']
|
||||
);
|
||||
// save only what changes
|
||||
this.changeMap[patchId] = {
|
||||
changes: cmp
|
||||
};
|
||||
});
|
||||
|
||||
console.log("change map", this.changeMap);
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -209,7 +209,7 @@ export class RecipeListComponent implements OnInit {
|
|||
],
|
||||
stirTime: [
|
||||
{
|
||||
value: recipeDetailMat.stirTime / 10,
|
||||
value: recipeDetailMat.stirTime,
|
||||
disabled: !this.isEditable(),
|
||||
},
|
||||
],
|
||||
|
|
@ -325,7 +325,7 @@ export class RecipeListComponent implements OnInit {
|
|||
],
|
||||
stirTime: [
|
||||
{
|
||||
value: recipeDetailMat.stirTime / 10,
|
||||
value: recipeDetailMat.stirTime,
|
||||
disabled: !this.isEditable(),
|
||||
},
|
||||
],
|
||||
|
|
@ -402,7 +402,7 @@ export class RecipeListComponent implements OnInit {
|
|||
);
|
||||
|
||||
// revert stirTime
|
||||
recipeDetailMat.stirTime = recipeDetailMat.stirTime! * 10;
|
||||
recipeDetailMat.stirTime = recipeDetailMat.stirTime!;
|
||||
|
||||
emitted_res.push(recipeDetailMat);
|
||||
});
|
||||
|
|
@ -633,7 +633,7 @@ export class RecipeListComponent implements OnInit {
|
|||
isMixOrder = (index: number) => {
|
||||
let mixOrder = this.recipeListData.at(index).get('MixOrder')?.value;
|
||||
|
||||
console.log("get::MixOrder", mixOrder, "test get::mixOrder", this.recipeListData.at(index).get('mixOrder'));
|
||||
// console.log("get::MixOrder", mixOrder, "test get::mixOrder", this.recipeListData.at(index).get('mixOrder'));
|
||||
// retry if not exist
|
||||
// if (!mixOrder) {
|
||||
// mixOrder = this.recipeListData.at(index).get('mixOrder')!.value;
|
||||
|
|
|
|||
73
client/src/app/shared/helpers/compare.ts
Normal file
73
client/src/app/shared/helpers/compare.ts
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
export function compare(
|
||||
base: any,
|
||||
updated: any,
|
||||
ignore?: string[],
|
||||
pathInit = '',
|
||||
sep = '.'
|
||||
): any[] {
|
||||
// recursive loop
|
||||
let compare_results = [];
|
||||
|
||||
// check if array
|
||||
if (Array.isArray(base) && Array.isArray(updated)) {
|
||||
for (let i = 0; i < base.length; i++) {
|
||||
compare_results.push(
|
||||
...compare(
|
||||
base[i],
|
||||
updated[i],
|
||||
ignore,
|
||||
pathInit + sep + i.toString(),
|
||||
sep
|
||||
)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
|
||||
if(updated == null || updated == undefined || base == null || base == undefined){
|
||||
return [];
|
||||
}
|
||||
|
||||
//
|
||||
let base_keys = Object.keys(base);
|
||||
let updated_keys = Object.keys(updated);
|
||||
|
||||
for (let key of base_keys) {
|
||||
if (ignore != undefined && ignore != null) {
|
||||
if (ignore.includes(key)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
const base_value = base[key];
|
||||
const updated_value = updated[key];
|
||||
|
||||
let isObj =
|
||||
base_value != undefined &&
|
||||
base_value != null &&
|
||||
typeof base_value === 'object' &&
|
||||
updated_value != undefined &&
|
||||
updated_value != null &&
|
||||
typeof updated_value === 'object';
|
||||
|
||||
if (isObj) {
|
||||
compare_results.push(
|
||||
...compare(
|
||||
base_value,
|
||||
updated_value,
|
||||
ignore,
|
||||
pathInit + sep + key,
|
||||
sep
|
||||
)
|
||||
);
|
||||
} else if (base_value != updated_value) {
|
||||
compare_results.push({
|
||||
key: pathInit + sep + key,
|
||||
value: base_value,
|
||||
change_to: updated_value,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return compare_results;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue