mirror of
https://github.com/goharbor/harbor.git
synced 2024-12-27 02:58:05 +01:00
Improve replication policy datagrid (#16806)
Signed-off-by: AllForNothing <sshijun@vmware.com>
This commit is contained in:
parent
16f38bc591
commit
584245ec4d
@ -22,3 +22,7 @@ export enum BandwidthUnit {
|
||||
MB = 'Mbps',
|
||||
KB = 'Kbps'
|
||||
}
|
||||
export enum ReplicationExecutionFilter {
|
||||
TRIGGER = 'trigger',
|
||||
STATUS = 'status'
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ import { DatePickerComponent } from "../../../../../shared/components/datetime-p
|
||||
import { FilterComponent } from "../../../../../shared/components/filter/filter.component";
|
||||
import { InlineAlertComponent } from "../../../../../shared/components/inline-alert/inline-alert.component";
|
||||
import {
|
||||
ReplicationRule,
|
||||
ReplicationJob,
|
||||
ReplicationJobItem
|
||||
} from "../../../../../shared/services";
|
||||
@ -21,15 +20,16 @@ import {delay} from "rxjs/operators";
|
||||
import { SharedTestingModule } from "../../../../../shared/shared.module";
|
||||
import { RegistryService } from "../../../../../../../ng-swagger-gen/services/registry.service";
|
||||
import { Registry } from "../../../../../../../ng-swagger-gen/models/registry";
|
||||
import { ReplicationPolicy } from '../../../../../../../ng-swagger-gen/models/replication-policy';
|
||||
|
||||
describe("CreateEditRuleComponent (inline template)", () => {
|
||||
let mockRules: ReplicationRule[] = [
|
||||
let mockRules: ReplicationPolicy[] = [
|
||||
{
|
||||
id: 1,
|
||||
name: "sync_01",
|
||||
description: "",
|
||||
src_registry: {id: 2},
|
||||
src_namespaces: ["name1", "name2"],
|
||||
dest_namespace: "",
|
||||
trigger: {
|
||||
type: "Manual",
|
||||
trigger_settings: {}
|
||||
@ -137,11 +137,11 @@ describe("CreateEditRuleComponent (inline template)", () => {
|
||||
}
|
||||
];
|
||||
|
||||
let mockRule: ReplicationRule = {
|
||||
let mockRule: ReplicationPolicy = {
|
||||
id: 1,
|
||||
name: "sync_01",
|
||||
description: "",
|
||||
src_namespaces: ["namespace1", "namespace2"],
|
||||
dest_namespace: "",
|
||||
src_registry: {id: 10 },
|
||||
dest_registry: {id: 0 },
|
||||
trigger: {
|
||||
|
@ -20,7 +20,7 @@ import {
|
||||
EventEmitter,
|
||||
Output
|
||||
} from "@angular/core";
|
||||
import { Filter, ReplicationRule } from "../../../../../shared/services";
|
||||
import { Filter } from "../../../../../shared/services";
|
||||
import { forkJoin, Observable, Subject, Subscription } from "rxjs";
|
||||
import { debounceTime, distinctUntilChanged, finalize } from "rxjs/operators";
|
||||
import { FormArray, FormBuilder, FormGroup, Validators, FormControl } from "@angular/forms";
|
||||
@ -37,6 +37,7 @@ import { Label } from "../../../../../../../ng-swagger-gen/models/label";
|
||||
import { LabelService } from "../../../../../../../ng-swagger-gen/services/label.service";
|
||||
import { BandwidthUnit, Decoration, Flatten_I18n_MAP, Flatten_Level } from "../../replication";
|
||||
import { errorHandler as errorHandlerFn} from '../../../../../shared/units/shared.utils';
|
||||
import { ReplicationPolicy } from '../../../../../../../ng-swagger-gen/models/replication-policy';
|
||||
|
||||
const PREFIX: string = '0 ';
|
||||
const PAGE_SIZE: number = 100;
|
||||
@ -71,7 +72,7 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
||||
policyId: number;
|
||||
confirmSub: Subscription;
|
||||
ruleForm: FormGroup;
|
||||
copyUpdateForm: ReplicationRule;
|
||||
copyUpdateForm: ReplicationPolicy;
|
||||
cronString: string;
|
||||
supportedTriggers: string[];
|
||||
supportedFilters: Filter[];
|
||||
@ -292,7 +293,7 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
|
||||
updateRuleFormAndCopyUpdateForm(rule: ReplicationRule): void {
|
||||
updateRuleFormAndCopyUpdateForm(rule: ReplicationPolicy): void {
|
||||
this.isPushMode = rule.dest_registry.id !== 0;
|
||||
setTimeout(() => {
|
||||
// convert speed unit to KB or MB
|
||||
@ -407,7 +408,7 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
// add new Replication rule
|
||||
this.inProgress = true;
|
||||
let copyRuleForm: ReplicationRule = this.ruleForm.value;
|
||||
let copyRuleForm: ReplicationPolicy = this.ruleForm.value;
|
||||
// need to convert unit to KB for speed property
|
||||
copyRuleForm.speed = this.convertToKB(copyRuleForm.speed);
|
||||
copyRuleForm.dest_namespace_replace_count = copyRuleForm.dest_namespace_replace_count
|
||||
@ -457,7 +458,7 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
||||
});
|
||||
}
|
||||
}
|
||||
openCreateEditRule(rule?: ReplicationRule): void {
|
||||
openCreateEditRule(rule?: ReplicationPolicy): void {
|
||||
this.formReset();
|
||||
this.copyUpdateForm = clone(this.ruleForm.value);
|
||||
this.inlineAlert.close();
|
||||
@ -474,8 +475,8 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
||||
this.supportedFilterLabels.forEach((label, index) => {
|
||||
if (rule.filters && rule.filters.length) {
|
||||
rule.filters.forEach(f => {
|
||||
if (f.type === FilterType.LABEL && f.value && f.value.length) {
|
||||
f.value.forEach(name => {
|
||||
if (f.type === FilterType.LABEL && f.value && (f.value as any).length) {
|
||||
(f.value as any).forEach(name => {
|
||||
if (label.name === name) {
|
||||
this.supportedFilterLabels[index].select = true;
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
<clr-datagrid (clrDgRefresh)="clrLoad($event)" [clrDgLoading]="loading" [(clrDgSingleSelected)]="selectedRow" (clrDgSingleSelectedChange)="selectRule($event)">
|
||||
<clr-dg-action-bar>
|
||||
<button type="button" id="new_replication_rule_id" class="btn btn-secondary" *ngIf="hasCreateReplicationPermission" (click)="openModal()"><clr-icon shape="plus" size="16"></clr-icon> {{'REPLICATION.NEW_REPLICATION_RULE' | translate}}</button>
|
||||
<button type="button" id="replication_exe_id" class="btn btn-secondary" *ngIf="hasExecuteReplicationPermission" [disabled]="!selectedRow" (click)="replicateRule(selectedRow)"><clr-icon shape="export" size="16"></clr-icon> {{'REPLICATION.REPLICATE' | translate}}</button>
|
||||
<button type="button" id="replication_exe_id" class="btn btn-secondary" *ngIf="hasExecuteReplicationPermission" [disabled]="!selectedRow || !selectedRow.enabled" (click)="replicateRule(selectedRow)"><clr-icon shape="export" size="16"></clr-icon> {{'REPLICATION.REPLICATE' | translate}}</button>
|
||||
<clr-dropdown
|
||||
[clrCloseMenuOnItemClick]="false"
|
||||
class="btn btn-link"
|
||||
@ -47,7 +47,7 @@
|
||||
<clr-dg-column class="col-width">{{'REPLICATION.REPLICATION_MODE' | translate}}</clr-dg-column>
|
||||
<clr-dg-column class="min-width">{{'REPLICATION.DESTINATION_NAMESPACE' | translate}}</clr-dg-column>
|
||||
<clr-dg-column>{{'REPLICATION.DES_REPO_FLATTENING' | translate}}</clr-dg-column>
|
||||
<clr-dg-column [clrDgField]="'trigger'">{{'REPLICATION.REPLICATION_TRIGGER' | translate}}</clr-dg-column>
|
||||
<clr-dg-column>{{'REPLICATION.REPLICATION_TRIGGER' | translate}}</clr-dg-column>
|
||||
<clr-dg-column [clrDgSortBy]="'speed'">{{'REPLICATION.BANDWIDTH' | translate}}</clr-dg-column>
|
||||
<clr-dg-column [clrDgField]="'description'">{{'REPLICATION.DESCRIPTION' | translate}}</clr-dg-column>
|
||||
<clr-dg-placeholder>{{'REPLICATION.PLACEHOLDER' | translate }}</clr-dg-placeholder>
|
||||
|
@ -1,27 +1,26 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ConfirmationDialogComponent } from '../../../../../shared/components/confirmation-dialog';
|
||||
import { ListReplicationRuleComponent } from './list-replication-rule.component';
|
||||
import { ReplicationRule } from '../../../../../shared/services';
|
||||
import { ErrorHandler } from '../../../../../shared/units/error-handler';
|
||||
import { ReplicationService } from '../../../../../shared/services';
|
||||
import { OperationService } from "../../../../../shared/components/operation/operation.service";
|
||||
import { of } from 'rxjs';
|
||||
import { delay } from "rxjs/operators";
|
||||
import {HttpHeaders, HttpResponse} from "@angular/common/http";
|
||||
import { SharedTestingModule } from "../../../../../shared/shared.module";
|
||||
import { ReplicationPolicy } from '../../../../../../../ng-swagger-gen/models/replication-policy';
|
||||
import { ReplicationService } from 'ng-swagger-gen/services/replication.service';
|
||||
|
||||
describe('ListReplicationRuleComponent (inline template)', () => {
|
||||
|
||||
let mockRules: ReplicationRule[] = [
|
||||
let mockRules: ReplicationPolicy[] = [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "sync_01",
|
||||
"description": "",
|
||||
"filters": null,
|
||||
"trigger": {"type": "Manual", "trigger_settings": null},
|
||||
"error_job_count": 2,
|
||||
"deletion": false,
|
||||
"src_namespaces": ["name1", "name2"],
|
||||
"dest_namespace": "",
|
||||
"src_registry": {id: 3},
|
||||
"enabled": true,
|
||||
"override": true,
|
||||
@ -33,9 +32,8 @@ describe('ListReplicationRuleComponent (inline template)', () => {
|
||||
"description": "",
|
||||
"filters": null,
|
||||
"trigger": {"type": "Manual", "trigger_settings": null},
|
||||
"error_job_count": 2,
|
||||
"deletion": false,
|
||||
"src_namespaces": ["name1", "name2"],
|
||||
"dest_namespace": "",
|
||||
"dest_registry": {id: 3},
|
||||
"enabled": true,
|
||||
"override": true,
|
||||
@ -47,13 +45,13 @@ describe('ListReplicationRuleComponent (inline template)', () => {
|
||||
|
||||
let comp: ListReplicationRuleComponent;
|
||||
const fakedReplicationService = {
|
||||
updateReplicationRule() {
|
||||
updateReplicationPolicy() {
|
||||
return of(true).pipe(delay(0));
|
||||
},
|
||||
deleteReplicationRule() {
|
||||
deleteReplicationPolicy() {
|
||||
return of(true).pipe(delay(0));
|
||||
},
|
||||
getReplicationRulesResponse() {
|
||||
listReplicationPoliciesResponse() {
|
||||
return of(new HttpResponse({
|
||||
body: mockRules,
|
||||
headers: new HttpHeaders({
|
||||
|
@ -11,28 +11,20 @@
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
import {
|
||||
Component,
|
||||
Input,
|
||||
Output,
|
||||
EventEmitter,
|
||||
ViewChild,
|
||||
} from "@angular/core";
|
||||
import { Component, EventEmitter, Input, Output, ViewChild, } from "@angular/core";
|
||||
import { TranslateService } from "@ngx-translate/core";
|
||||
import { map, catchError, finalize } from "rxjs/operators";
|
||||
import { Observable, forkJoin, throwError as observableThrowError } from "rxjs";
|
||||
import { ReplicationService } from "../../../../../shared/services";
|
||||
import {
|
||||
ReplicationRule
|
||||
} from "../../../../../shared/services";
|
||||
import { catchError, finalize, map } from "rxjs/operators";
|
||||
import { forkJoin, Observable, throwError as observableThrowError } from "rxjs";
|
||||
import { ConfirmationDialogComponent } from "../../../../../shared/components/confirmation-dialog";
|
||||
import {
|
||||
ConfirmationState,
|
||||
ConfirmationTargets,
|
||||
ConfirmationButtons
|
||||
} from "../../../../../shared/entities/shared.const";
|
||||
import { ConfirmationButtons, ConfirmationState, ConfirmationTargets } from "../../../../../shared/entities/shared.const";
|
||||
import { ErrorHandler } from "../../../../../shared/units/error-handler";
|
||||
import { clone, getPageSizeFromLocalStorage, PageSizeMapKeys, setPageSizeToLocalStorage } from "../../../../../shared/units/utils";
|
||||
import {
|
||||
clone,
|
||||
getPageSizeFromLocalStorage, getQueryString,
|
||||
getSortingString,
|
||||
PageSizeMapKeys,
|
||||
setPageSizeToLocalStorage
|
||||
} from "../../../../../shared/units/utils";
|
||||
import { operateChanges, OperateInfo, OperationState } from "../../../../../shared/components/operation/operate";
|
||||
import { OperationService } from "../../../../../shared/components/operation/operation.service";
|
||||
import { ClrDatagridStateInterface } from '@clr/angular';
|
||||
@ -42,12 +34,15 @@ import { ConfirmationMessage } from "../../../../global-confirmation-dialog/conf
|
||||
import { HELM_HUB } from "../../../../../shared/services/endpoint.service";
|
||||
import { BandwidthUnit, Flatten_I18n_MAP } from "../../replication";
|
||||
import { KB_TO_MB } from "../create-edit-rule/create-edit-rule.component";
|
||||
import { ReplicationService } from "ng-swagger-gen/services/replication.service";
|
||||
import { ReplicationPolicy } from '../../../../../../../ng-swagger-gen/models/replication-policy';
|
||||
|
||||
@Component({
|
||||
selector: "hbr-list-replication-rule",
|
||||
templateUrl: "./list-replication-rule.component.html",
|
||||
styleUrls: ["./list-replication-rule.component.scss"],
|
||||
})
|
||||
export class ListReplicationRuleComponent {
|
||||
export class ListReplicationRuleComponent {
|
||||
@Input() selectedId: number | string;
|
||||
@Input() withReplicationJob: boolean;
|
||||
@Input() hasCreateReplicationPermission: boolean;
|
||||
@ -55,15 +50,15 @@ export class ListReplicationRuleComponent {
|
||||
@Input() hasDeleteReplicationPermission: boolean;
|
||||
@Input() hasExecuteReplicationPermission: boolean;
|
||||
@Input() searchString: string;
|
||||
@Output() selectOne = new EventEmitter<ReplicationRule>();
|
||||
@Output() editOne = new EventEmitter<ReplicationRule>();
|
||||
@Output() toggleOne = new EventEmitter<ReplicationRule>();
|
||||
@Output() selectOne = new EventEmitter<ReplicationPolicy>();
|
||||
@Output() editOne = new EventEmitter<ReplicationPolicy>();
|
||||
@Output() toggleOne = new EventEmitter<ReplicationPolicy>();
|
||||
@Output() hideJobs = new EventEmitter<any>();
|
||||
@Output() redirect = new EventEmitter<ReplicationRule>();
|
||||
@Output() redirect = new EventEmitter<ReplicationPolicy>();
|
||||
@Output() openNewRule = new EventEmitter<any>();
|
||||
@Output() replicateManual = new EventEmitter<ReplicationRule>();
|
||||
rules: ReplicationRule[] = [];
|
||||
selectedRow: ReplicationRule;
|
||||
@Output() replicateManual = new EventEmitter<ReplicationPolicy>();
|
||||
rules: ReplicationPolicy[] = [];
|
||||
selectedRow: ReplicationPolicy;
|
||||
@ViewChild("toggleConfirmDialog")
|
||||
toggleConfirmDialog: ConfirmationDialogComponent;
|
||||
@ViewChild("deletionConfirmDialog")
|
||||
@ -74,9 +69,9 @@ export class ListReplicationRuleComponent {
|
||||
loading: boolean = true;
|
||||
|
||||
constructor(private replicationService: ReplicationService,
|
||||
private translateService: TranslateService,
|
||||
private errorHandlerEntity: ErrorHandler,
|
||||
private operationService: OperationService) {
|
||||
private translateService: TranslateService,
|
||||
private errorHandlerEntity: ErrorHandler,
|
||||
private operationService: OperationService) {
|
||||
}
|
||||
|
||||
trancatedDescription(desc: string): string {
|
||||
@ -86,9 +81,11 @@ export class ListReplicationRuleComponent {
|
||||
return desc;
|
||||
}
|
||||
}
|
||||
replicateRule(rule: ReplicationRule): void {
|
||||
|
||||
replicateRule(rule: ReplicationPolicy): void {
|
||||
this.replicateManual.emit(rule);
|
||||
}
|
||||
|
||||
deletionConfirm(message: ConfirmationAcknowledgement) {
|
||||
if (
|
||||
message &&
|
||||
@ -97,10 +94,10 @@ export class ListReplicationRuleComponent {
|
||||
) {
|
||||
this.deleteOpe(message.data);
|
||||
}
|
||||
if ( message &&
|
||||
if (message &&
|
||||
message.source === ConfirmationTargets.REPLICATION &&
|
||||
message.state === ConfirmationState.CONFIRMED) {
|
||||
const rule: ReplicationRule = clone(message.data);
|
||||
const rule: ReplicationPolicy = clone(message.data);
|
||||
rule.enabled = !message.data.enabled;
|
||||
const opeMessage = new OperateInfo();
|
||||
opeMessage.name = rule.enabled ? 'REPLICATION.ENABLE_TITLE' : 'REPLICATION.DISABLE_TITLE';
|
||||
@ -108,34 +105,38 @@ export class ListReplicationRuleComponent {
|
||||
opeMessage.state = OperationState.progressing;
|
||||
opeMessage.data.name = rule.name;
|
||||
this.operationService.publishInfo(opeMessage);
|
||||
this.replicationService.updateReplicationRule(rule.id, rule).subscribe(
|
||||
res => {
|
||||
this.replicationService.updateReplicationPolicy({
|
||||
id: rule.id,
|
||||
policy: rule
|
||||
}).subscribe({
|
||||
next: () => {
|
||||
this.translateService.get(rule.enabled ? 'REPLICATION.ENABLE_SUCCESS' : 'REPLICATION.DISABLE_SUCCESS')
|
||||
.subscribe(msg => {
|
||||
operateChanges(opeMessage, OperationState.success);
|
||||
this.errorHandlerEntity.info(msg);
|
||||
this.refreshRule();
|
||||
});
|
||||
}, error => {
|
||||
operateChanges(opeMessage, OperationState.success);
|
||||
this.errorHandlerEntity.info(msg);
|
||||
this.refreshRule();
|
||||
});
|
||||
},
|
||||
error: error => {
|
||||
const errMessage = errorHandler(error);
|
||||
this.translateService.get(rule.enabled ? 'REPLICATION.ENABLE_FAILED' : 'REPLICATION.DISABLE_FAILED')
|
||||
.subscribe(msg => {
|
||||
operateChanges(opeMessage, OperationState.failure, msg);
|
||||
this.errorHandlerEntity.error(errMessage);
|
||||
});
|
||||
operateChanges(opeMessage, OperationState.failure, msg);
|
||||
this.errorHandlerEntity.error(errMessage);
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
selectRule(rule: ReplicationRule): void {
|
||||
selectRule(rule: ReplicationPolicy): void {
|
||||
if (rule) {
|
||||
this.selectedId = rule.id || "";
|
||||
this.selectOne.emit(rule);
|
||||
}
|
||||
}
|
||||
|
||||
redirectTo(rule: ReplicationRule): void {
|
||||
redirectTo(rule: ReplicationPolicy): void {
|
||||
this.redirect.emit(rule);
|
||||
}
|
||||
|
||||
@ -143,11 +144,11 @@ export class ListReplicationRuleComponent {
|
||||
this.openNewRule.emit();
|
||||
}
|
||||
|
||||
editRule(rule: ReplicationRule) {
|
||||
editRule(rule: ReplicationPolicy) {
|
||||
this.editOne.emit(rule);
|
||||
}
|
||||
|
||||
deleteRule(rule: ReplicationRule) {
|
||||
deleteRule(rule: ReplicationPolicy) {
|
||||
if (rule) {
|
||||
let deletionMessage = new ConfirmationMessage(
|
||||
"REPLICATION.DELETION_TITLE",
|
||||
@ -161,7 +162,7 @@ export class ListReplicationRuleComponent {
|
||||
}
|
||||
}
|
||||
|
||||
deleteOpe(rule: ReplicationRule) {
|
||||
deleteOpe(rule: ReplicationPolicy) {
|
||||
if (rule) {
|
||||
let observableLists: any[] = [];
|
||||
observableLists.push(this.delOperate(rule));
|
||||
@ -175,7 +176,7 @@ export class ListReplicationRuleComponent {
|
||||
}
|
||||
}
|
||||
|
||||
delOperate(rule: ReplicationRule): Observable<any> {
|
||||
delOperate(rule: ReplicationPolicy): Observable<any> {
|
||||
// init operation info
|
||||
let operMessage = new OperateInfo();
|
||||
operMessage.name = 'OPERATION.DELETE_REPLICATION';
|
||||
@ -185,11 +186,13 @@ export class ListReplicationRuleComponent {
|
||||
this.operationService.publishInfo(operMessage);
|
||||
|
||||
return this.replicationService
|
||||
.deleteReplicationRule(+rule.id)
|
||||
.pipe(map(() => {
|
||||
this.translateService.get('BATCH.DELETED_SUCCESS')
|
||||
.subscribe(res => operateChanges(operMessage, OperationState.success));
|
||||
.deleteReplicationPolicy({
|
||||
id: rule.id
|
||||
})
|
||||
.pipe(map(() => {
|
||||
this.translateService.get('BATCH.DELETED_SUCCESS')
|
||||
.subscribe(res => operateChanges(operMessage, OperationState.success));
|
||||
})
|
||||
, catchError(error => {
|
||||
const message = errorHandler(error);
|
||||
this.translateService.get(message).subscribe(res =>
|
||||
@ -198,7 +201,8 @@ export class ListReplicationRuleComponent {
|
||||
return observableThrowError(error);
|
||||
}));
|
||||
}
|
||||
operateRule(operation: string, rule: ReplicationRule): void {
|
||||
|
||||
operateRule(operation: string, rule: ReplicationPolicy): void {
|
||||
let title: string;
|
||||
let summary: string;
|
||||
let buttons: ConfirmationButtons;
|
||||
@ -228,32 +232,44 @@ export class ListReplicationRuleComponent {
|
||||
);
|
||||
this.deletionConfirmDialog.open(msg);
|
||||
}
|
||||
|
||||
clrLoad(state?: ClrDatagridStateInterface) {
|
||||
if (state && state.page) {
|
||||
this.pageSize = state.page.size;
|
||||
setPageSizeToLocalStorage(PageSizeMapKeys.LIST_REPLICATION_RULE_COMPONENT, this.pageSize);
|
||||
}
|
||||
this.loading = true;
|
||||
this.replicationService.getReplicationRulesResponse(
|
||||
this.searchString,
|
||||
this.page,
|
||||
this.pageSize)
|
||||
const param: ReplicationService.ListReplicationPoliciesParams = {
|
||||
page: this.page,
|
||||
pageSize: this.pageSize,
|
||||
sort: getSortingString(state),
|
||||
};
|
||||
if (this.searchString) {
|
||||
param.q = encodeURIComponent(`name=~${this.searchString}`);
|
||||
} else {
|
||||
param.q = getQueryString(state);
|
||||
}
|
||||
this.replicationService.listReplicationPoliciesResponse(param)
|
||||
.pipe(finalize(() => this.loading = false))
|
||||
.subscribe(response => {
|
||||
// job list hidden
|
||||
this.hideJobs.emit();
|
||||
// Get total count
|
||||
if (response.headers) {
|
||||
let xHeader: string = response.headers.get("x-total-count");
|
||||
if (xHeader) {
|
||||
this.totalCount = parseInt(xHeader, 0);
|
||||
}
|
||||
}
|
||||
this.rules = response.body as ReplicationRule[];
|
||||
}, error => {
|
||||
this.errorHandlerEntity.error(error);
|
||||
.subscribe({
|
||||
next: response => {
|
||||
// job list hidden
|
||||
this.hideJobs.emit();
|
||||
// Get total count
|
||||
if (response.headers) {
|
||||
let xHeader: string = response.headers.get("x-total-count");
|
||||
if (xHeader) {
|
||||
this.totalCount = parseInt(xHeader, 0);
|
||||
}
|
||||
}
|
||||
this.rules = response.body as ReplicationPolicy[];
|
||||
},
|
||||
error: error => {
|
||||
this.errorHandlerEntity.error(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
refreshRule() {
|
||||
this.page = 1;
|
||||
this.totalCount = 0;
|
||||
@ -261,15 +277,18 @@ export class ListReplicationRuleComponent {
|
||||
this.searchString = null;
|
||||
this.clrLoad();
|
||||
}
|
||||
|
||||
isHelmHub(srcRegistry: any): boolean {
|
||||
return srcRegistry && srcRegistry.type === HELM_HUB;
|
||||
return srcRegistry && srcRegistry.type === HELM_HUB;
|
||||
}
|
||||
|
||||
getFlattenLevelString(level: number) {
|
||||
if (level !== null && Flatten_I18n_MAP[level]) {
|
||||
return Flatten_I18n_MAP[level];
|
||||
}
|
||||
return level;
|
||||
}
|
||||
|
||||
getBandwidthStr(speed: number): string {
|
||||
if (speed >= KB_TO_MB) {
|
||||
return '' + (speed / KB_TO_MB).toFixed(2) + BandwidthUnit.MB;
|
||||
|
@ -12,7 +12,7 @@
|
||||
</div>
|
||||
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
|
||||
<hbr-list-replication-rule #listReplicationRule (replicateManual)=replicateManualRule($event)
|
||||
(selectOne)="selectOneRule($event)" (hideJobs)="hideJobs()" (openNewRule)="openModal()" (editOne)="openEditRule($event)" [withReplicationJob]="withReplicationJob" (redirect)="customRedirect($event)"
|
||||
(selectOne)="selectOneRule($event)" (hideJobs)="hideJobs()" (openNewRule)="openModal()" (editOne)="openEditRule($event)" [withReplicationJob]="withReplicationJob"
|
||||
[hasCreateReplicationPermission]="hasCreateReplicationPermission"
|
||||
[hasUpdateReplicationPermission]="hasUpdateReplicationPermission"
|
||||
[hasDeleteReplicationPermission]="hasDeleteReplicationPermission"
|
||||
|
@ -4,10 +4,9 @@ import { NoopAnimationsModule } from "@angular/platform-browser/animations";
|
||||
import { ConfirmationDialogComponent } from '../../../../shared/components/confirmation-dialog';
|
||||
import { ReplicationComponent } from './replication.component';
|
||||
import { CronScheduleComponent } from '../../../../shared/components/cron-schedule';
|
||||
import { ReplicationRule, ReplicationJob, Endpoint} from '../../../../shared/services';
|
||||
import { ReplicationJob, Endpoint} from '../../../../shared/services';
|
||||
import { CronTooltipComponent } from "../../../../shared/components/cron-schedule";
|
||||
import { ErrorHandler } from '../../../../shared/units/error-handler';
|
||||
import { ReplicationService } from '../../../../shared/services';
|
||||
import { ReplicationJobItem } from '../../../../shared/services';
|
||||
import { OperationService } from "../../../../shared/components/operation/operation.service";
|
||||
import { RouterTestingModule } from '@angular/router/testing';
|
||||
@ -15,21 +14,22 @@ import { of, Subscription } from 'rxjs';
|
||||
import { HttpHeaders, HttpResponse } from "@angular/common/http";
|
||||
import { delay } from "rxjs/operators";
|
||||
import { SharedTestingModule } from "../../../../shared/shared.module";
|
||||
import { ReplicationPolicy } from '../../../../../../ng-swagger-gen/models/replication-policy';
|
||||
import { ReplicationService } from 'ng-swagger-gen/services/replication.service';
|
||||
|
||||
|
||||
describe('Replication Component (inline template)', () => {
|
||||
|
||||
let mockRules: ReplicationRule[] = [
|
||||
let mockRules: ReplicationPolicy[] = [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "sync_01",
|
||||
"description": "",
|
||||
"filters": null,
|
||||
"trigger": {"type": "Manual", "trigger_settings": null},
|
||||
"error_job_count": 2,
|
||||
"deletion": false,
|
||||
"src_registry": {id: 3},
|
||||
"src_namespaces": ["name1"],
|
||||
"dest_namespace": "",
|
||||
"enabled": true,
|
||||
"override": true,
|
||||
"speed": -1
|
||||
@ -40,10 +40,9 @@ describe('Replication Component (inline template)', () => {
|
||||
"description": "",
|
||||
"filters": null,
|
||||
"trigger": {"type": "Manual", "trigger_settings": null},
|
||||
"error_job_count": 2,
|
||||
"deletion": false,
|
||||
"dest_registry": {id: 5},
|
||||
"src_namespaces": ["name1"],
|
||||
"dest_namespace": "",
|
||||
"enabled": true,
|
||||
"override": true,
|
||||
"speed": -1
|
||||
@ -127,7 +126,7 @@ describe('Replication Component (inline template)', () => {
|
||||
}
|
||||
};
|
||||
const fakedReplicationService = {
|
||||
getReplicationRulesResponse() {
|
||||
listReplicationPoliciesResponse() {
|
||||
return of(new HttpResponse({
|
||||
body: mockRules,
|
||||
headers: new HttpHeaders({
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -5,7 +5,6 @@
|
||||
[isSystemAdmin]="isSystemAdmin"
|
||||
[withAdmiral]="withAdmiral"
|
||||
(goToRegistry)="goRegistry()"
|
||||
(redirect)="customRedirect($event)"
|
||||
[hasCreateReplicationPermission]="true"
|
||||
[hasUpdateReplicationPermission]="true"
|
||||
[hasDeleteReplicationPermission]="true"
|
||||
|
@ -15,7 +15,6 @@ import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { Router, ActivatedRoute, NavigationEnd } from "@angular/router";
|
||||
import {SessionService} from "../../../shared/services/session.service";
|
||||
import {AppConfigService} from "../../../services/app-config.service";
|
||||
import { ReplicationRule } from "../../../shared/services";
|
||||
import { Subscription } from "rxjs";
|
||||
import { EventService, HarborEvent } from "../../../services/event-service/event.service";
|
||||
// The route path which will display this component
|
||||
@ -64,11 +63,6 @@ export class TotalReplicationPageComponent implements OnInit, OnDestroy {
|
||||
this.scrollSub = null;
|
||||
}
|
||||
}
|
||||
customRedirect(rule: ReplicationRule): void {
|
||||
if (rule) {
|
||||
this.router.navigate(['../projects', rule.projects[0].project_id, 'replications'], { relativeTo: this.activeRoute });
|
||||
}
|
||||
}
|
||||
goRegistry(): void {
|
||||
this.router.navigate(['harbor', 'registries']);
|
||||
}
|
||||
|
@ -7,8 +7,9 @@ import {
|
||||
HTTP_GET_OPTIONS, CURRENT_BASE_HREF
|
||||
} from "../units/utils";
|
||||
import { RequestQueryParams } from "./index";
|
||||
import { Endpoint, ReplicationRule, PingEndpoint } from "./index";
|
||||
import { Endpoint, PingEndpoint } from "./index";
|
||||
import { catchError, map } from "rxjs/operators";
|
||||
import { ReplicationPolicy } from '../../../../ng-swagger-gen/models/replication-policy';
|
||||
|
||||
export const ADAPTERS_MAP = {
|
||||
"ali-acr": "Alibaba ACR",
|
||||
@ -264,7 +265,7 @@ export class EndpointDefaultService extends EndpointService {
|
||||
let requestUrl: string = `${this._endpointUrl}/${endpointId}/policies`;
|
||||
return this.http
|
||||
.get(requestUrl, HTTP_GET_OPTIONS)
|
||||
.pipe(map(response => response as ReplicationRule[])
|
||||
.pipe(map(response => response as ReplicationPolicy[])
|
||||
, catchError(error => observableThrowError(error)));
|
||||
}
|
||||
|
||||
|
@ -53,32 +53,6 @@ export interface Filter {
|
||||
values?: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface for replication rule.
|
||||
*
|
||||
**
|
||||
* interface ReplicationRule
|
||||
* interface Filter
|
||||
* interface Trigger
|
||||
*/
|
||||
export interface ReplicationRule extends Base {
|
||||
[key: string]: any;
|
||||
id?: number;
|
||||
name: string;
|
||||
description: string;
|
||||
trigger: Trigger;
|
||||
filters: Filter[];
|
||||
deletion?: boolean;
|
||||
src_registry?: any;
|
||||
dest_registry?: any;
|
||||
src_namespaces: string[];
|
||||
dest_namespace?: string;
|
||||
dest_namespace_replace_count?: number;
|
||||
enabled: boolean;
|
||||
override: boolean;
|
||||
speed: number;
|
||||
}
|
||||
|
||||
export class Filter {
|
||||
type: string;
|
||||
value?: any;
|
||||
|
@ -9,13 +9,13 @@ import {
|
||||
} from "../units/utils";
|
||||
import {
|
||||
ReplicationJob,
|
||||
ReplicationRule,
|
||||
ReplicationJobItem,
|
||||
ReplicationTasks
|
||||
} from "./interface";
|
||||
import { RequestQueryParams } from "./RequestQueryParams";
|
||||
import { map, catchError } from "rxjs/operators";
|
||||
import { Observable, throwError as observableThrowError } from "rxjs";
|
||||
import { ReplicationPolicy } from '../../../../ng-swagger-gen/models/replication-policy';
|
||||
|
||||
/**
|
||||
* Define the service methods to handle the replication (rule and job) related things.
|
||||
@ -44,13 +44,13 @@ export abstract class ReplicationService {
|
||||
ruleName?: string,
|
||||
queryParams?: RequestQueryParams
|
||||
):
|
||||
| Observable<ReplicationRule[]>;
|
||||
| Observable<ReplicationPolicy[]>;
|
||||
abstract getReplicationRulesResponse(
|
||||
ruleName?: string,
|
||||
page?: number ,
|
||||
pageSize?: number,
|
||||
queryParams?: RequestQueryParams
|
||||
): Observable<HttpResponse<ReplicationRule[]>>;
|
||||
): Observable<HttpResponse<ReplicationPolicy[]>>;
|
||||
|
||||
/**
|
||||
* Get the specified replication rule.
|
||||
@ -63,7 +63,7 @@ export abstract class ReplicationService {
|
||||
*/
|
||||
abstract getReplicationRule(
|
||||
ruleId: number | string
|
||||
): Observable<ReplicationRule>;
|
||||
): Observable<ReplicationPolicy>;
|
||||
|
||||
|
||||
/**
|
||||
@ -88,7 +88,7 @@ export abstract class ReplicationService {
|
||||
* @memberOf ReplicationService
|
||||
*/
|
||||
abstract createReplicationRule(
|
||||
replicationRule: ReplicationRule
|
||||
replicationRule: ReplicationPolicy
|
||||
): Observable<any>;
|
||||
|
||||
/**
|
||||
@ -102,7 +102,7 @@ export abstract class ReplicationService {
|
||||
*/
|
||||
abstract updateReplicationRule(
|
||||
id: number,
|
||||
rep: ReplicationRule
|
||||
rep: ReplicationPolicy
|
||||
): Observable<any>;
|
||||
|
||||
/**
|
||||
@ -229,7 +229,7 @@ export class ReplicationDefaultService extends ReplicationService {
|
||||
|
||||
// Private methods
|
||||
// Check if the rule object is valid
|
||||
_isValidRule(rule: ReplicationRule): boolean {
|
||||
_isValidRule(rule: ReplicationPolicy): boolean {
|
||||
return (
|
||||
rule !== undefined &&
|
||||
rule != null &&
|
||||
@ -255,7 +255,7 @@ export class ReplicationDefaultService extends ReplicationService {
|
||||
ruleName?: string,
|
||||
queryParams?: RequestQueryParams
|
||||
):
|
||||
| Observable<ReplicationRule[]> {
|
||||
| Observable<ReplicationPolicy[]> {
|
||||
if (!queryParams) {
|
||||
queryParams = new RequestQueryParams();
|
||||
}
|
||||
@ -269,14 +269,14 @@ export class ReplicationDefaultService extends ReplicationService {
|
||||
}
|
||||
return this.http
|
||||
.get(this._ruleBaseUrl, buildHttpRequestOptions(queryParams))
|
||||
.pipe(map(response => response as ReplicationRule[])
|
||||
.pipe(map(response => response as ReplicationPolicy[])
|
||||
, catchError(error => observableThrowError(error)));
|
||||
}
|
||||
public getReplicationRulesResponse(
|
||||
ruleName?: string,
|
||||
page?: number,
|
||||
pageSize?: number,
|
||||
queryParams?: RequestQueryParams): Observable<HttpResponse<ReplicationRule[]>> {
|
||||
queryParams?: RequestQueryParams): Observable<HttpResponse<ReplicationPolicy[]>> {
|
||||
if (!queryParams) {
|
||||
queryParams = new RequestQueryParams();
|
||||
}
|
||||
@ -290,14 +290,14 @@ export class ReplicationDefaultService extends ReplicationService {
|
||||
queryParams = queryParams.set("page_size", pageSize + "");
|
||||
}
|
||||
return this.http
|
||||
.get<HttpResponse<ReplicationRule[]>>(this._ruleBaseUrl, buildHttpRequestOptionsWithObserveResponse(queryParams))
|
||||
.pipe(map(response => response as HttpResponse<ReplicationRule[]>)
|
||||
.get<HttpResponse<ReplicationPolicy[]>>(this._ruleBaseUrl, buildHttpRequestOptionsWithObserveResponse(queryParams))
|
||||
.pipe(map(response => response as HttpResponse<ReplicationPolicy[]>)
|
||||
, catchError(error => observableThrowError(error)));
|
||||
}
|
||||
|
||||
public getReplicationRule(
|
||||
ruleId: number | string
|
||||
): Observable<ReplicationRule> {
|
||||
): Observable<ReplicationPolicy> {
|
||||
if (!ruleId) {
|
||||
return observableThrowError("Bad argument");
|
||||
}
|
||||
@ -305,7 +305,7 @@ export class ReplicationDefaultService extends ReplicationService {
|
||||
let url: string = `${this._ruleBaseUrl}/${ruleId}`;
|
||||
return this.http
|
||||
.get(url, HTTP_GET_OPTIONS)
|
||||
.pipe(map(response => response as ReplicationRule)
|
||||
.pipe(map(response => response as ReplicationPolicy)
|
||||
, catchError(error => observableThrowError(error)));
|
||||
}
|
||||
|
||||
@ -324,7 +324,7 @@ export class ReplicationDefaultService extends ReplicationService {
|
||||
}
|
||||
|
||||
public createReplicationRule(
|
||||
replicationRule: ReplicationRule
|
||||
replicationRule: ReplicationPolicy
|
||||
): Observable<any> {
|
||||
if (!this._isValidRule(replicationRule)) {
|
||||
return observableThrowError("Bad argument");
|
||||
@ -342,7 +342,7 @@ export class ReplicationDefaultService extends ReplicationService {
|
||||
|
||||
public updateReplicationRule(
|
||||
id: number,
|
||||
rep: ReplicationRule
|
||||
rep: ReplicationPolicy
|
||||
): Observable<any> {
|
||||
if (!this._isValidRule(rep)) {
|
||||
return observableThrowError("Bad argument");
|
||||
|
Loading…
Reference in New Issue
Block a user