Improve replication page (#14566)

Signed-off-by: AllForNothing <sshijun@vmware.com>
This commit is contained in:
Will Sun 2021-04-02 14:13:34 +08:00 committed by GitHub
parent 8b917c0ad3
commit f74759667c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 115 additions and 25 deletions

View File

@ -21,10 +21,10 @@ import {
Output
} from "@angular/core";
import { Filter, ReplicationRule, Endpoint } from "../../../../../shared/services/interface";
import { Subject, Subscription, Observable, zip } from "rxjs";
import { Subject, Subscription } from "rxjs";
import { debounceTime, distinctUntilChanged, finalize } from "rxjs/operators";
import { FormArray, FormBuilder, FormGroup, Validators, FormControl } from "@angular/forms";
import { clone, compareValue, isEmptyObject } from "../../../../../shared/units/utils";
import { clone, isEmptyObject, isSameObject } from "../../../../../shared/units/utils";
import { InlineAlertComponent } from "../../../../../shared/components/inline-alert/inline-alert.component";
import { ReplicationService } from "../../../../../shared/services";
import { ErrorHandler } from "../../../../../shared/units/error-handler";
@ -235,11 +235,7 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
updateRuleFormAndCopyUpdateForm(rule: ReplicationRule): void {
if (rule.dest_registry.id === 0) {
this.isPushMode = false;
} else {
this.isPushMode = true;
}
this.isPushMode = rule.dest_registry.id !== 0;
setTimeout(() => {
// There is no trigger_setting type when the harbor is upgraded from the old version.
rule.trigger.trigger_settings = rule.trigger.trigger_settings ? rule.trigger.trigger_settings : {cron: ''};
@ -507,17 +503,9 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
}
hasChanges(): boolean {
let formValue = clone(this.ruleForm.value);
let initValue = clone(this.copyUpdateForm);
let initValueCopy: any = {};
for (let key of Object.keys(formValue)) {
initValueCopy[key] = initValue[key];
}
if (!compareValue(formValue, initValueCopy)) {
return true;
}
return false;
const formValue = clone(this.ruleForm.value);
const initValue = clone(this.copyUpdateForm);
return !isSameObject(formValue, initValue);
}

View File

@ -478,8 +478,12 @@ export class ReplicationComponent implements OnInit, OnDestroy {
refreshRules() {
this.search.ruleName = "";
this.filterComponent.currentValue = "";
this.listReplicationRule.refreshRule();
if (this.filterComponent.currentValue) {
this.filterComponent.currentValue = "";
this.filterComponent.filterTerms.next(''); // will trigger refreshing
} else {
this.listReplicationRule.refreshRule(); // manually refresh
}
}
refreshJobs() {
@ -497,11 +501,7 @@ export class ReplicationComponent implements OnInit, OnDestroy {
}
openFilter(isOpen: boolean): void {
if (isOpen) {
this.isOpenFilterTag = true;
} else {
this.isOpenFilterTag = false;
}
this.isOpenFilterTag = isOpen;
}
getDuration(j: ReplicationJobItem) {
if (!j) {

View File

@ -0,0 +1,25 @@
import { isSameArrayValue, isSameObject } from "./utils";
describe('functions in utils.ts should work', () => {
it('function isSameArrayValue() should work', () => {
expect(isSameArrayValue).toBeTruthy();
expect(isSameArrayValue(null, null)).toBeFalsy();
expect(isSameArrayValue([], null)).toBeFalsy();
expect(isSameArrayValue([1, 2, 3], [3 , 2, 1])).toBeTruthy();
expect(isSameArrayValue([{a: 1, c: 2}, true], [true, {c: 2, a: 1, d: null}])).toBeTruthy();
});
it('function isSameObject() should work', () => {
expect(isSameObject).toBeTruthy();
expect(isSameObject(null, null)).toBeTruthy();
expect(isSameObject({}, null)).toBeFalsy();
expect(isSameObject(null, {})).toBeFalsy();
expect(isSameObject([], null)).toBeFalsy();
expect(isSameObject(null, [])).toBeFalsy();
expect(isSameObject({a: 1, b: true}, {a: 1})).toBeFalsy();
expect(isSameObject({a: 1, b: false}, {a: 1})).toBeFalsy();
expect(isSameObject({a: [1, 2, 3], b: null}, {a: [3, 2, 1]})).toBeTruthy();
expect(isSameObject({a: {a: 1 , b: 2}, b: null}, {a: {b: 2, a: 1}})).toBeTruthy();
expect(isSameObject([1, 2, 3], [3 , 2, 1])).toBeFalsy();
});
});

View File

@ -646,3 +646,80 @@ export function getSortingString(state: ClrDatagridStateInterface): string {
}
return null;
}
/**
* if two object are the same
* @param a
* @param b
*/
export function isSameObject(a: any, b: any): boolean {
if (a && !b) {
return false;
}
if (b && !a) {
return false;
}
if (a && b) {
if (Array.isArray(a) || Array.isArray(b)) {
return false;
}
const c: any = Object.keys(a).length > Object.keys(b).length ? a : b;
for (const key in c) {
if (c.hasOwnProperty(key)) {
if (!c[key]) {
// should not use triple-equals here
// tslint:disable-next-line:triple-equals
if (a[key] != b[key]) {
return false;
}
} else {
if (Array.isArray(c[key])) {
if (!isSameArrayValue(a[key], b[key])) {
return false;
}
} else if (isObject(c[key])) {
if (!isSameObject(a[key], b[key])) {
return false;
}
} else {
// should not use triple-equals here
// tslint:disable-next-line:triple-equals
if (a[key] != b[key]) {
return false;
}
}
}
}
}
}
return true;
}
/**
* if two arrays have the same length and contain the same items, they are regarded as the same
* @param a
* @param b
*/
export function isSameArrayValue(a: any, b: any): boolean {
if (a && b && Array.isArray(a) && Array.isArray(a)) {
if (a.length !== b.length) {
return false;
}
let isSame: boolean = true;
a.forEach(itemOfA => {
let hasItem: boolean = false;
b.forEach(itemOfB => {
if (isSameObject(itemOfA, itemOfB)) {
hasItem = true;
}
});
if (!hasItem) {
isSame = false;
}
});
if (isSame) {
return true;
}
}
return false;
}