From 7642938f61707904436636319637738af40f3396 Mon Sep 17 00:00:00 2001
From: Matthijs Smets <93487259+MatthijsSmets@users.noreply.github.com>
Date: Thu, 18 Jul 2024 11:36:10 +0200
Subject: [PATCH] Refactor: refactor compare tab (#512)
* refactor: removed the jqx-widgets library and refactored the compare tab because of it
* refactor: process pr comments
* Test new CICD job
---
.github/workflows/testing.js.yml | 12 +
angular.json | 9 +-
package.json | 4 +-
pnpm-lock.yaml | 25 +-
src/app/compare/compare-data.ts | 3 -
.../compare-tree/compare-tree.component.css | 17 +-
.../compare-tree/compare-tree.component.html | 22 +-
.../compare-tree.component.spec.ts | 4 +-
.../compare-tree/compare-tree.component.ts | 293 +++++++-----------
src/app/compare/compare.component.css | 11 +
src/app/compare/compare.component.html | 43 ++-
src/app/compare/compare.component.ts | 103 +++---
.../debug/debug-tree/debug-tree.component.ts | 2 +-
src/app/debug/table/table.component.html | 20 +-
src/app/debug/table/table.component.ts | 16 +-
src/app/shared/enums/compare-method.ts | 5 -
src/app/shared/enums/node-link-strategy.ts | 2 +
src/app/shared/pipes/str-replace.pipe.ts | 11 +
src/app/shared/services/helper.service.ts | 139 ---------
src/app/shared/util/report-util.ts | 11 +-
src/app/test/test.component.ts | 2 -
src/main.ts | 9 +-
src/styles.css | 4 +
23 files changed, 292 insertions(+), 475 deletions(-)
delete mode 100644 src/app/shared/enums/compare-method.ts
create mode 100644 src/app/shared/enums/node-link-strategy.ts
create mode 100644 src/app/shared/pipes/str-replace.pipe.ts
diff --git a/.github/workflows/testing.js.yml b/.github/workflows/testing.js.yml
index ef669242..4cfed3a2 100644
--- a/.github/workflows/testing.js.yml
+++ b/.github/workflows/testing.js.yml
@@ -69,6 +69,18 @@ jobs:
run: pnpm install --frozen-lockfile
working-directory: ladybug-frontend
+ - name: Install Cypress
+ run: npx cypress install
+ working-directory: ladybug-frontend
+
+ - uses: actions/cache@v4
+ name: Cache Cypress
+ with:
+ path: ~/.cache/Cypress
+ key: ${{ runner.os }}-cypress-${{ hashFiles('**/package-lock.json') }}
+ restore-keys: |
+ ${{ runner.os }}-cypress-
+
- name: Set Cypress environment variables
run: cp cypress.env.json.cicd cypress.env.json
working-directory: ladybug-frontend
diff --git a/angular.json b/angular.json
index 29ad0cb3..b2bab741 100644
--- a/angular.json
+++ b/angular.json
@@ -55,8 +55,7 @@
"node_modules/bootstrap/dist/css/bootstrap.min.css",
"./node_modules/@angular/material/prebuilt-themes/indigo-pink.css",
"src/styles.css",
- "node_modules/font-awesome/css/font-awesome.css",
- "./node_modules/jqwidgets-ng/jqwidgets/styles/jqx.base.css"
+ "node_modules/font-awesome/css/font-awesome.css"
],
"scripts": []
},
@@ -129,11 +128,7 @@
"styles": [
"node_modules/@angular/material/prebuilt-themes/indigo-pink.css",
"node_modules/bootstrap/dist/css/bootstrap.min.css",
- "src/styles.css",
- "node_modules/jqwidgets-ng/jqwidgets/styles/jqx.base.css"
- ],
- "scripts": [
- "node_modules/jquery/dist/jquery.slim.min.js"
+ "src/styles.css"
]
}
},
diff --git a/package.json b/package.json
index 920f85cb..fe5deebc 100644
--- a/package.json
+++ b/package.json
@@ -47,10 +47,8 @@
"eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-unicorn": "^54.0.0",
"font-awesome": "^4.7.0",
- "jquery": "^3.7.1",
- "jqwidgets-ng": "^14.1.17",
"monaco-editor": "0.44.0",
- "ng-simple-file-tree": "^0.1.13",
+ "ng-simple-file-tree": "^0.1.19",
"ngx-monaco-editor-v2": "17.0.1",
"path": "^0.12.7",
"popper.js": "^1.16.1",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index a95eea00..c23f5902 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -86,18 +86,12 @@ importers:
font-awesome:
specifier: ^4.7.0
version: 4.7.0
- jquery:
- specifier: ^3.7.1
- version: 3.7.1
- jqwidgets-ng:
- specifier: ^14.1.17
- version: 14.1.20
monaco-editor:
specifier: 0.44.0
version: 0.44.0
ng-simple-file-tree:
- specifier: ^0.1.13
- version: 0.1.14(bootstrap-icons@1.11.3)
+ specifier: ^0.1.19
+ version: 0.1.19(@angular/common@17.0.8(@angular/core@17.0.8(rxjs@7.4.0)(zone.js@0.14.3))(rxjs@7.4.0))(@angular/core@17.0.8(rxjs@7.4.0)(zone.js@0.14.3))(bootstrap-icons@1.11.3)
ngx-monaco-editor-v2:
specifier: 17.0.1
version: 17.0.1(@angular/common@17.0.8(@angular/core@17.0.8(rxjs@7.4.0)(zone.js@0.14.3))(rxjs@7.4.0))(@angular/core@17.0.8(rxjs@7.4.0)(zone.js@0.14.3))(monaco-editor@0.44.0)
@@ -3717,9 +3711,6 @@ packages:
jquery@3.7.1:
resolution: {integrity: sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==}
- jqwidgets-ng@14.1.20:
- resolution: {integrity: sha512-rApVo4/k1M4aj3AI5bn2nG/5pKmeCGSuCFTynLS0F0/iXYV6iegPC8bNzwui0qkQJ19a7I5IW3yyi1LaxJpttA==}
-
js-tokens@4.0.0:
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
@@ -4143,9 +4134,11 @@ packages:
neo-async@2.6.2:
resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==}
- ng-simple-file-tree@0.1.14:
- resolution: {integrity: sha512-Hg85jSqF2YNoFsjIIiKyMFjjJpOZ5Vg3lUe8G0fE0OwFkIZGh+ub/lfRd5DMXnBd5mzQ9UEal+ygDCCrC096pw==}
+ ng-simple-file-tree@0.1.19:
+ resolution: {integrity: sha512-WtoMPalo6oLAqouaH57OJSU0csIpqDbkR7fl4udTgZYpGS9/80WJV9W4wlwXD3qGpaRw13z/HepItlrHggK7Cg==}
peerDependencies:
+ '@angular/common': ^17.2.3
+ '@angular/core': ^17.3.2
bootstrap-icons: ^1.11.3
ngx-monaco-editor-v2@17.0.1:
@@ -10027,8 +10020,6 @@ snapshots:
jquery@3.7.1: {}
- jqwidgets-ng@14.1.20: {}
-
js-tokens@4.0.0: {}
js-yaml@3.14.1:
@@ -10457,8 +10448,10 @@ snapshots:
neo-async@2.6.2: {}
- ng-simple-file-tree@0.1.14(bootstrap-icons@1.11.3):
+ ng-simple-file-tree@0.1.19(@angular/common@17.0.8(@angular/core@17.0.8(rxjs@7.4.0)(zone.js@0.14.3))(rxjs@7.4.0))(@angular/core@17.0.8(rxjs@7.4.0)(zone.js@0.14.3))(bootstrap-icons@1.11.3):
dependencies:
+ '@angular/common': 17.0.8(@angular/core@17.0.8(rxjs@7.4.0)(zone.js@0.14.3))(rxjs@7.4.0)
+ '@angular/core': 17.0.8(rxjs@7.4.0)(zone.js@0.14.3)
bootstrap-icons: 1.11.3
tslib: 2.3.1
diff --git a/src/app/compare/compare-data.ts b/src/app/compare/compare-data.ts
index f25c53e0..30ae72a4 100644
--- a/src/app/compare/compare-data.ts
+++ b/src/app/compare/compare-data.ts
@@ -1,9 +1,6 @@
-import { NodeLinkStrategy } from '../shared/enums/compare-method';
-
export class CompareData {
id!: string;
originalReport: any;
runResultReport: any;
viewName: string = '';
- nodeLinkStrategy: NodeLinkStrategy = NodeLinkStrategy.NONE;
}
diff --git a/src/app/compare/compare-tree/compare-tree.component.css b/src/app/compare/compare-tree/compare-tree.component.css
index 40172c0b..edf6df32 100644
--- a/src/app/compare/compare-tree/compare-tree.component.css
+++ b/src/app/compare/compare-tree/compare-tree.component.css
@@ -1,18 +1,5 @@
-/*#tree-container {*/
-/* background: linear-gradient(#e9ecef, #e9ecef) no-repeat center/2px 100%;*/
-/*}*/
-
-.compare-header {
- display: flex;
- align-items: center;
- height: 50px;
- border-bottom: 1px solid #dee2e6;
-}
-
.trees-container {
+ display: flex;
+ flex-direction: row;
height: 46vh;
}
-
-label {
- margin: 0;
-}
diff --git a/src/app/compare/compare-tree/compare-tree.component.html b/src/app/compare/compare-tree/compare-tree.component.html
index 069bffdf..f8e8d5da 100644
--- a/src/app/compare/compare-tree/compare-tree.component.html
+++ b/src/app/compare/compare-tree/compare-tree.component.html
@@ -1,20 +1,4 @@
-
-
-
+
+
+
diff --git a/src/app/compare/compare-tree/compare-tree.component.spec.ts b/src/app/compare/compare-tree/compare-tree.component.spec.ts
index bdb1ab0a..aea8b069 100644
--- a/src/app/compare/compare-tree/compare-tree.component.spec.ts
+++ b/src/app/compare/compare-tree/compare-tree.component.spec.ts
@@ -1,8 +1,8 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { CompareTreeComponent } from './compare-tree.component';
-import { jqxTreeModule } from 'jqwidgets-ng/jqxtree';
import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { NgSimpleFileTreeModule } from 'ng-simple-file-tree';
describe('CompareTreeComponent', () => {
let component: CompareTreeComponent;
@@ -10,7 +10,7 @@ describe('CompareTreeComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
- imports: [jqxTreeModule, CompareTreeComponent, HttpClientTestingModule],
+ imports: [NgSimpleFileTreeModule, CompareTreeComponent, HttpClientTestingModule],
}).compileComponents();
});
diff --git a/src/app/compare/compare-tree/compare-tree.component.ts b/src/app/compare/compare-tree/compare-tree.component.ts
index 3fc66fbf..11024438 100644
--- a/src/app/compare/compare-tree/compare-tree.component.ts
+++ b/src/app/compare/compare-tree/compare-tree.component.ts
@@ -1,209 +1,156 @@
-import { Component, EventEmitter, Output, ViewChild } from '@angular/core';
+import { Component, EventEmitter, Input, Output, ViewChild } from '@angular/core';
import { Report } from '../../shared/interfaces/report';
-import { HelperService } from '../../shared/services/helper.service';
-import { jqxTreeComponent, jqxTreeModule } from 'jqwidgets-ng/jqxtree';
-import { NodeLinkStrategy } from '../../shared/enums/compare-method';
-import { ReactiveFormsModule } from '@angular/forms';
+import { FormsModule, ReactiveFormsModule } from '@angular/forms';
+import { TitleCasePipe } from '@angular/common';
+
+import { ReportHierarchyTransformer } from '../../shared/classes/report-hierarchy-transformer';
+import { ReportUtil } from '../../shared/util/report-util';
+import { CompareData } from '../compare-data';
+import { Checkpoint } from '../../shared/interfaces/checkpoint';
+import { NodeLinkStrategy } from '../../shared/enums/node-link-strategy';
+import {
+ CreateTreeItem,
+ FileTreeItem,
+ FileTreeOptions,
+ NgSimpleFileTree,
+ NgSimpleFileTreeModule,
+ OptionalParameters,
+} from 'ng-simple-file-tree';
+
+export const treeSideConst = ['left', 'right'] as const;
+export type TreeSide = (typeof treeSideConst)[number];
@Component({
selector: 'app-compare-tree',
templateUrl: './compare-tree.component.html',
styleUrls: ['./compare-tree.component.css'],
standalone: true,
- imports: [ReactiveFormsModule, jqxTreeModule],
+ imports: [ReactiveFormsModule, TitleCasePipe, FormsModule, NgSimpleFileTreeModule],
})
export class CompareTreeComponent {
- constructor(private helperService: HelperService) {}
- @Output() compareEvent = new EventEmitter
();
- @Output() changeNodeLinkStrategyEvent = new EventEmitter();
- @ViewChild('leftTreeReference') leftTreeReference!: jqxTreeComponent;
- @ViewChild('rightTreeReference') rightTreeReference!: jqxTreeComponent;
- nodeLinkStrategy: NodeLinkStrategy = NodeLinkStrategy.NONE;
- viewName: string = '';
- leftReport: any;
- rightReport: any;
-
- public get NodeLinkStrategy(): typeof NodeLinkStrategy {
- return NodeLinkStrategy;
- }
-
- nodeSelected(data: any, left: boolean) {
- this.selectOtherNode(data, left);
- this.compareEvent.emit({
- leftReport: this.leftReport,
- rightReport: this.rightReport,
- });
+ @Output() compareEvent: EventEmitter = new EventEmitter();
+ @ViewChild('leftTree') leftTree!: NgSimpleFileTree;
+ @ViewChild('rightTree') rightTree!: NgSimpleFileTree;
+ @Input({ required: true }) nodeLinkStrategy!: NodeLinkStrategy;
+ @Input({ required: true }) compareData!: CompareData;
+ leftReport?: Report;
+ rightReport?: Report;
+ left?: Report;
+ leftTreeOptions: FileTreeOptions = {
+ highlightOpenFolders: false,
+ folderBehaviourOnClick: 'select',
+ expandAllFolders: true,
+ };
+
+ rightTreeOptions: FileTreeOptions = {
+ highlightOpenFolders: false,
+ folderBehaviourOnClick: 'select',
+ expandAllFolders: true,
+ determineFontColor: (item: CreateTreeItem) => this.setRedLabels(item),
+ };
+
+ createTrees(leftReport: Report, rightReport: Report): void {
+ this.leftReport = new ReportHierarchyTransformer().transform(leftReport);
+ this.rightReport = new ReportHierarchyTransformer().transform(rightReport);
+ const optional: OptionalParameters = { childrenKey: 'checkpoints' };
+ this.leftTree.addItem(this.leftReport, optional);
+ this.rightTree.addItem(this.rightReport, optional);
+ this.selectFirstItem();
}
- selectOtherNode(data: any, left: boolean) {
- if (this.nodeLinkStrategy === 'NONE') {
- this.compareOnNothing(data, left);
- } else {
- this.compareOnSomething(this.nodeLinkStrategy, data, left);
+ setRedLabels(item: CreateTreeItem): string {
+ if (ReportUtil.isReport(item)) {
+ return this.namesMatch(item.name, this.leftReport?.name);
}
- }
- compareOnSomething(method: string, data: any, left: boolean) {
- let treeReference: jqxTreeComponent = left ? this.rightTreeReference : this.leftTreeReference;
- let selectedReport = data.owner.selectedItem;
-
- let otherReport =
- method === 'PATH'
- ? this.getOtherReportBasedOnPath(selectedReport, treeReference)
- : this.getOtherReportBasedOnCheckpointNumber(selectedReport, treeReference);
-
- if (otherReport) {
- this.unfoldTree(treeReference, otherReport, otherReport.parentId);
- treeReference.selectItem(otherReport);
- } else {
- treeReference.selectItem(null);
+ if (ReportUtil.isCheckPoint(item)) {
+ const checkpoint: Checkpoint | null = this.findCorrespondingCheckpoint(item, this.leftReport);
+ return this.namesMatch(item.name, checkpoint?.name);
}
-
- this.leftReport = left ? selectedReport : otherReport;
- this.rightReport = left ? otherReport : selectedReport;
- }
-
- getOtherReportBasedOnCheckpointNumber(selectedReport: any, treeReference: jqxTreeComponent) {
- let checkpointNumber = selectedReport.value.index;
- return treeReference.getItems().find((item: any) => checkpointNumber == item.value.index);
- }
-
- getOtherReportBasedOnPath(selectedReport: any, treeReference: jqxTreeComponent) {
- let path = this.getFullPath(selectedReport, [selectedReport.value.name]);
- return this.matchFullPath(treeReference.getItems()[0], path);
- }
- compareOnNothing(data: any, left: boolean) {
- left ? (this.leftReport = data.owner.selectedItem) : (this.rightReport = data.owner.selectedItem);
- }
-
- changeNodeLinkStrategy(event: any) {
- this.nodeLinkStrategy = event.target.value;
- this.changeNodeLinkStrategyEvent.next(this.nodeLinkStrategy);
- localStorage.setItem(this.viewName + '.NodeLinkStrategy', this.nodeLinkStrategy);
- }
- getParent(checkpoint: any, parentId: string): any {
- let items = checkpoint.treeInstance.items;
- return items.find((item: any) => item.id == parentId);
+ return '';
}
- unfoldTree(treeReference: any, checkpoint: any, parentId: string) {
- while (parentId.toString() !== '0') {
- treeReference.expandItem(checkpoint);
- parentId = checkpoint.parentId;
- checkpoint = this.getParent(checkpoint, checkpoint.parentId);
+ selectFirstItem(): void {
+ if (ReportUtil.isReport(this.leftReport!)) {
+ this.leftTree.selectItem(this.leftReport.path);
+ }
+ if (ReportUtil.isReport(this.rightReport)) {
+ this.rightTree.selectItem(this.rightReport.path);
}
+ this.compareEvent.emit();
}
- getFullPath(checkpoint: any, pathSoFar: string[]): string[] {
- let parent = this.getParent(checkpoint, checkpoint.parentId);
- if (parent) {
- pathSoFar.push(parent.value.name);
- return this.getFullPath(parent, pathSoFar);
+ syncTrees(treeSide: TreeSide): void {
+ if (treeSide === 'left') {
+ this.selectItem(this.rightTree, this.leftTree.getSelected());
+ } else if (treeSide === 'right') {
+ this.selectItem(this.leftTree, this.rightTree.getSelected());
}
-
- return pathSoFar;
}
- matchFullPath(checkpoint: any, path: string[]): any {
- if (path.length === 0) return checkpoint;
-
- let toBeSelected = null;
- let firstPart = path.shift();
- checkpoint.treeInstance.items.every((item: any) => {
- if (item.value.name === firstPart) {
- let result = this.checkIfSameParents(item, item.parentId, path);
- if (result) {
- toBeSelected = item;
- return false; //Breaking since we found him;
- }
+ selectItem(otherSide: NgSimpleFileTree, treeItem: FileTreeItem): void {
+ switch (this.nodeLinkStrategy) {
+ case 'PATH': {
+ otherSide.selectItem(treeItem.path);
+ break;
+ }
+ case 'CHECKPOINT_NUMBER': {
+ this.selectByCheckPointNumber(otherSide, treeItem.originalValue as Report | Checkpoint);
}
- return true;
- });
-
- return toBeSelected;
- }
-
- checkIfSameParents(checkpoint: string, parentId: string, path: string[]): boolean {
- if (path.length === 0) return true;
- let parent = this.getParent(checkpoint, parentId);
- if (parent && parent.value.name == path[0]) {
- path.shift();
- return this.checkIfSameParents(parent, parent.parentId, path);
}
- return false;
+ this.compareEvent.emit();
}
- createTrees(viewName: string, nodeLinkStrategy: NodeLinkStrategy, leftReport: Report, rightReport: Report) {
- this.viewName = viewName;
- this.nodeLinkStrategy = nodeLinkStrategy;
- let nls = localStorage.getItem(this.viewName + '.NodeLinkStrategy');
- if (nls) {
- this.nodeLinkStrategy = NodeLinkStrategy[nls as keyof typeof NodeLinkStrategy];
+ selectByCheckPointNumber(tree: NgSimpleFileTree, treeItem: Report | Checkpoint): void {
+ if (ReportUtil.isReport(treeItem)) {
+ tree.selectItem(tree.getItems()[0].path);
+ } else if (ReportUtil.isCheckPoint(treeItem)) {
+ this.selectCheckpoint(tree, tree.getItems()[0], treeItem);
}
- const leftTree = this.helperService.convertReportToJqxTree(leftReport);
- const rightTree = this.helperService.convertReportToJqxTree(rightReport);
- const both = this.iterateToMakeLabelsRed(leftTree, rightTree);
-
- this.leftTreeReference.createComponent({
- height: '100%',
- source: [both.left],
- });
- this.rightTreeReference.createComponent({
- height: '100%',
- source: [both.right],
- });
-
- this.selectFirstItem();
- }
-
- selectFirstItem() {
- this.leftReport = this.leftTreeReference.getItems()[0];
- this.rightReport = this.rightTreeReference.getItems()[0];
- this.leftTreeReference.selectItem(this.leftReport);
- this.rightTreeReference.selectItem(this.rightReport);
- this.compareEvent.emit({
- leftReport: this.leftReport,
- rightReport: this.rightReport,
- });
- }
-
- makeLabelsRed(left: any, right: any) {
- this.redLabel(left);
- this.redLabel(right);
- }
-
- redLabel(item: any) {
- item.label = `${item.label}`;
}
- iterateToMakeLabelsRed(leftItem: any, rightItem: any) {
- let result = this.checkIfLabelsDifferent(leftItem, rightItem);
- const shortestTreeLength = Math.min(leftItem.items.length, rightItem.items.length);
- this.makeRestOfTreesRed(shortestTreeLength, rightItem.items, leftItem.items);
-
- for (let i = 0; i < shortestTreeLength; i++) {
- let both = this.iterateToMakeLabelsRed(leftItem.items[i], rightItem.items[i]);
- leftItem.items[i] = both.left;
- rightItem.items[i] = both.right;
+ selectCheckpoint(tree: NgSimpleFileTree, item: FileTreeItem, checkpointToMatch: Checkpoint): void {
+ if (item.children) {
+ for (const child of item.children) {
+ const checkpoint = child.originalValue as Checkpoint;
+ if (this.getCheckpointId(checkpoint.uid) === this.getCheckpointId(checkpointToMatch.uid)) {
+ tree.selectItem(child.path);
+ return;
+ } else {
+ this.selectCheckpoint(tree, child, checkpointToMatch);
+ }
+ }
}
-
- return result;
}
- makeRestOfTreesRed(startPoint: number, leftItems: any[], rightItems: any[]) {
- let items = leftItems;
- if (rightItems.length > leftItems.length) items = rightItems;
- for (let i = startPoint; i < items.length; i++) {
- this.redLabel(items[i]);
+ namesMatch(name1: string | undefined, name2?: string | undefined): string {
+ if (name1 && name2 && name1 === name2) {
+ return '';
}
- }
-
- checkIfLabelsDifferent(left: any, right: any): { left: any; right: any } {
- if (left.level > -1) {
- if (left.value.message !== right.value.message) this.makeLabelsRed(left, right);
- } else {
- if (left.value.xml !== right.value.xml) this.makeLabelsRed(left, right);
+ return 'red';
+ }
+
+ findCorrespondingCheckpoint(
+ itemToMatch: Checkpoint | Report,
+ report: Report | Checkpoint | undefined,
+ ): Checkpoint | null {
+ if (report) {
+ const checkpoints: Checkpoint[] = report.checkpoints ?? [];
+ for (let checkpoint of checkpoints) {
+ if (
+ ReportUtil.isCheckPoint(itemToMatch) &&
+ this.getCheckpointId(checkpoint.uid) === this.getCheckpointId(itemToMatch.uid)
+ ) {
+ return checkpoint;
+ }
+ if (checkpoint.checkpoints) {
+ return this.findCorrespondingCheckpoint(itemToMatch, checkpoint);
+ }
+ }
}
+ return null;
+ }
- return { left: left, right: right };
+ getCheckpointId(uid: string): string {
+ return uid.split('#')[1];
}
}
diff --git a/src/app/compare/compare.component.css b/src/app/compare/compare.component.css
index 2d2ecfd0..f5bd78c9 100644
--- a/src/app/compare/compare.component.css
+++ b/src/app/compare/compare.component.css
@@ -5,6 +5,17 @@
height: 94vh;
}
+.compare-header {
+ display: flex;
+ align-items: center;
+ height: 50px;
+ border-bottom: 1px solid #dee2e6;
+
+ & > label {
+ margin: 0;
+ }
+}
+
.trees {
resize: vertical;
overflow: auto;
diff --git a/src/app/compare/compare.component.html b/src/app/compare/compare.component.html
index 4c699d07..249258a2 100644
--- a/src/app/compare/compare.component.html
+++ b/src/app/compare/compare.component.html
@@ -1,21 +1,36 @@
+
+
@if (compareData) {
-
-
+ [compareData]="compareData"
+ [nodeLinkStrategy]="nodeLinkStrategy"
+ (compareEvent)="showDifference()"
+ />
+ }
+
+ @if (compareData) {
-
-
- }
+ }
+
+
+
diff --git a/src/app/compare/compare.component.ts b/src/app/compare/compare.component.ts
index 3903ca06..24028be9 100644
--- a/src/app/compare/compare.component.ts
+++ b/src/app/compare/compare.component.ts
@@ -1,37 +1,49 @@
import { AfterViewInit, Component, OnInit, ViewChild } from '@angular/core';
import { CompareTreeComponent } from './compare-tree/compare-tree.component';
-import { NodeLinkStrategy } from '../shared/enums/compare-method';
import { CompareData } from './compare-data';
import { DiffEditorModel, MonacoEditorModule } from 'ngx-monaco-editor-v2';
import { TabService } from '../shared/services/tab.service';
import { ActivatedRoute, Router } from '@angular/router';
import { DisplayTableComponent } from '../shared/components/display-table/display-table.component';
+import { FormsModule, ReactiveFormsModule } from '@angular/forms';
+import { TitleCasePipe } from '@angular/common';
+import { NodeLinkStrategy, nodeLinkStrategyConst } from '../shared/enums/node-link-strategy';
+import { Report } from '../shared/interfaces/report';
+import { Checkpoint } from '../shared/interfaces/checkpoint';
+import { ReportUtil } from '../shared/util/report-util';
+import { StrReplacePipe } from '../shared/pipes/str-replace.pipe';
@Component({
selector: 'app-compare',
templateUrl: './compare.component.html',
styleUrls: ['./compare.component.css'],
standalone: true,
- imports: [CompareTreeComponent, DisplayTableComponent, MonacoEditorModule],
+ imports: [
+ CompareTreeComponent,
+ DisplayTableComponent,
+ MonacoEditorModule,
+ ReactiveFormsModule,
+ TitleCasePipe,
+ FormsModule,
+ StrReplacePipe,
+ ],
})
-export class CompareComponent implements OnInit, AfterViewInit {
- static readonly leftReportKey: string = 'leftId';
- static readonly rightReportKey: string = 'rightId';
+export class CompareComponent implements AfterViewInit, OnInit {
static readonly ROUTER_PATH: string = 'compare';
- @ViewChild('trees') compareTreeComponent!: CompareTreeComponent;
- diffOptions = { theme: 'vs', language: 'xml', readOnly: true, renderSideBySide: true, automaticLayout: true };
- originalModel: DiffEditorModel = {
- code: '',
+ @ViewChild(CompareTreeComponent) compareTreeComponent!: CompareTreeComponent;
+ protected readonly nodeLinkStrategyConst = nodeLinkStrategyConst;
+ protected nodeLinkStrategy!: NodeLinkStrategy;
+ protected diffOptions = {
+ theme: 'vs',
language: 'xml',
+ readOnly: true,
+ renderSideBySide: true,
+ automaticLayout: true,
};
+ protected originalModel: DiffEditorModel = { code: '', language: 'xml' };
+ protected modifiedModel: DiffEditorModel = { code: '', language: 'xml' };
- modifiedModel: DiffEditorModel = {
- code: '',
- language: 'xml',
- };
- id?: string;
-
- compareData: CompareData | undefined;
+ protected compareData?: CompareData;
constructor(
public tabService: TabService,
@@ -41,60 +53,55 @@ export class CompareComponent implements OnInit, AfterViewInit {
ngOnInit(): void {
this.compareData = this.getData(this.getIdsFromPath());
+ this.getStrategyFromLocalStorage();
+ }
+
+ ngAfterViewInit(): void {
if (this.compareData) {
this.renderDiffs(this.compareData.originalReport.xml, this.compareData.runResultReport.xml);
+ this.showReports();
} else {
this.router.navigate(['debug']);
}
}
- ngAfterViewInit(): void {
- setTimeout(() => {
- this.showReports();
- }, 100);
+ private getData(id: string): CompareData | undefined {
+ return this.tabService.activeCompareTabs.get(id);
}
- getIdsFromPath(): string {
+ private getIdsFromPath(): string {
return this.route.snapshot.paramMap.get('id') as string;
}
- getData(id: string): CompareData | undefined {
- return this.tabService.activeCompareTabs.get(id);
+ private renderDiffs(leftSide: string, rightSide: string): void {
+ this.originalModel = { ...this.originalModel, code: leftSide };
+ this.modifiedModel = { ...this.originalModel, code: rightSide };
}
- showReports(): void {
- if (this.compareData && this.compareData.originalReport && this.compareData.runResultReport) {
- this.compareTreeComponent?.createTrees(
- this.compareData.viewName,
- this.compareData.nodeLinkStrategy,
- this.compareData.originalReport,
- this.compareData.runResultReport,
- );
+ private getStrategyFromLocalStorage(): void {
+ if (this.compareData) {
+ const strategy: string | null = localStorage.getItem(this.compareData.viewName + '.NodeLinkStrategy');
+ this.nodeLinkStrategy = strategy ? (strategy as NodeLinkStrategy) : 'NONE';
}
}
- showDifference(data: any): void {
- const leftSide = data.leftReport ? this.extractMessage(data.leftReport) : '';
- const rightSide = data.rightReport ? this.extractMessage(data.rightReport) : '';
- this.renderDiffs(leftSide, rightSide);
+ private showReports(): void {
+ this.compareTreeComponent.createTrees(this.compareData!.originalReport, this.compareData!.runResultReport);
}
- changeNodeLinkStrategy(nodeLinkStrategy: NodeLinkStrategy): void {
- if (this.compareData) {
- this.compareData.nodeLinkStrategy = nodeLinkStrategy;
- }
+ protected showDifference(): void {
+ const leftSide = this.extractMessage(this.compareTreeComponent.leftTree.getSelected().originalValue);
+ const rightSide = this.extractMessage(this.compareTreeComponent.rightTree.getSelected().originalValue);
+ this.renderDiffs(leftSide, rightSide);
}
- extractMessage(report: any): string {
- return report.parentElement ? report.value.message ?? '' : report.value.xml ?? '';
+ private extractMessage(selectedNode: Report | Checkpoint): string {
+ return ReportUtil.isReport(selectedNode) ? selectedNode.xml : selectedNode.message;
}
- renderDiffs(leftSide: string, rightSide: string): void {
- this.originalModel = Object.assign({}, this.originalModel, {
- code: leftSide,
- });
- this.modifiedModel = Object.assign({}, this.originalModel, {
- code: rightSide,
- });
+ protected changeNodeLinkStrategy(): void {
+ if (this.compareData && this.nodeLinkStrategy) {
+ localStorage.setItem(this.compareData.viewName + '.NodeLinkStrategy', this.nodeLinkStrategy);
+ }
}
}
diff --git a/src/app/debug/debug-tree/debug-tree.component.ts b/src/app/debug/debug-tree/debug-tree.component.ts
index 83ddfd6e..bbf4a7ec 100644
--- a/src/app/debug/debug-tree/debug-tree.component.ts
+++ b/src/app/debug/debug-tree/debug-tree.component.ts
@@ -1,7 +1,7 @@
import { Component, EventEmitter, Input, OnDestroy, Output, ViewChild } from '@angular/core';
import { Report } from '../../shared/interfaces/report';
import { HelperService } from '../../shared/services/helper.service';
-import { Observable, Subscription, catchError, of } from 'rxjs';
+import { catchError, Observable, Subscription } from 'rxjs';
import { HttpService } from '../../shared/services/http.service';
import { SettingsService } from '../../shared/services/settings.service';
import {
diff --git a/src/app/debug/table/table.component.html b/src/app/debug/table/table.component.html
index 19b469ec..0ae61795 100644
--- a/src/app/debug/table/table.component.html
+++ b/src/app/debug/table/table.component.html
@@ -75,7 +75,7 @@