mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-26 12:15:20 +01:00
Merge pull request #7227 from zhoumeina/replication_ng
add filter logic
This commit is contained in:
commit
c0faa9d4aa
@ -2,15 +2,6 @@
|
||||
<h3 class="modal-title">{{headerTitle | translate}}</h3>
|
||||
<hbr-inline-alert class="modal-title" (confirmEvt)="confirmCancel($event)"></hbr-inline-alert>
|
||||
<div class="modal-body modal-body-height">
|
||||
<clr-alert [hidden]='!deletedLabelCount' [clrAlertType]="'alert-warning'" [clrAlertSizeSmall]="true" [clrAlertClosable]="false"
|
||||
[(clrAlertClosed)]="alertClosed">
|
||||
<div class="alert-item">
|
||||
<span class="alert-text">{{deletedLabelInfo}}</span>
|
||||
<div class="alert-actions">
|
||||
<a class="alert-action" (click)=" alertClosed = true">{{'REPLICATION.ACKNOWLEDGE' | translate}}</a>
|
||||
</div>
|
||||
</div>
|
||||
</clr-alert>
|
||||
<form [formGroup]="ruleForm" novalidate>
|
||||
<section class="form-block">
|
||||
<div class="form-group form-group-override">
|
||||
@ -55,7 +46,7 @@
|
||||
<label class="form-group-label-override required">{{'REPLICATION.SOURCE_NAMESPACES' | translate}}</label>
|
||||
<div formArrayName="src_namespaces">
|
||||
<div class="width-315" *ngFor="let src_namespace of src_namespaces.controls; let i=index">
|
||||
<div class="select endpointSelect pull-left">
|
||||
<div class="endpointSelect pull-left">
|
||||
<label aria-haspopup="true" role="tooltip" class="tooltip tooltip-validation tooltip-md tooltip-bottom-left" [class.invalid]='(src_namespace.touched && src_namespace.invalid)'>
|
||||
<input type="text" [formControlName]="i" pattern="^[a-z0-9]+(?:[._-][a-z0-9]+)*$" class="inputWidth" required maxlength="255">
|
||||
<span class="tooltip-content">{{'REPLICATION.NAMESPACE_TOOLTIP' | translate}}</span>
|
||||
@ -64,7 +55,7 @@
|
||||
<clr-icon shape="times-circle" class="is-solid" (click)="deleteNamespace(i)"></clr-icon>
|
||||
</div>
|
||||
</div>
|
||||
<clr-icon id="addSourceNamespace" shape="plus-circle" class="is-solid mr-t-15" (click)="addNewNamespace()"></clr-icon>
|
||||
<clr-icon id="addSourceNamespace" shape="plus-circle" class="is-solid mr-t-10" (click)="addNewNamespace()"></clr-icon>
|
||||
</div>
|
||||
<!--images/Filter-->
|
||||
<div class="form-group form-group-override">
|
||||
@ -72,24 +63,20 @@
|
||||
<div formArrayName="filters">
|
||||
<div class="filterSelect" *ngFor="let filter of filters.controls; let i=index">
|
||||
<div [formGroupName]="i">
|
||||
<div class="select floatSetPar">
|
||||
<select formControlName="kind" #selectedValue (change)="filterChange($event, selectedValue.value)" id="{{i}}" name="{{filterListData[i]?.name}}">
|
||||
<option *ngFor="let opt of filterListData[i]?.options;" value="{{opt}}">{{opt}}</option>
|
||||
</select>
|
||||
<div class="floatSetPar">
|
||||
<label>{{supportedFilters[i].type}}:</label>
|
||||
</div>
|
||||
<label aria-haspopup="true" role="tooltip" class="tooltip tooltip-validation tooltip-md tooltip-bottom-left" [class.invalid]='(filter.value.dirty || filter.value.touched) && filter.value.invalid'>
|
||||
<input type="text" #filterValue required size="14" formControlName="value" [attr.disabled]="(filterListData[i]?.name=='label') ?'' : null">
|
||||
<label *ngIf="supportedFilters[i]?.style==='input'" aria-haspopup="true" role="tooltip" class="tooltip tooltip-validation tooltip-md tooltip-bottom-left"
|
||||
[class.invalid]='(filter.value.dirty || filter.value.touched) && filter.value.invalid'>
|
||||
<input type="text" #filterValue required size="14" formControlName="value">
|
||||
<span class="tooltip-content">{{'TOOLTIP.EMPTY' | translate}}</span>
|
||||
</label>
|
||||
<div class="arrowSet" [hidden]="!(filterListData[i]?.name=='label')" (click)="openLabelList(selectedValue.value, i, $event)">
|
||||
<clr-icon shape="angle"></clr-icon>
|
||||
</div>
|
||||
<clr-icon shape="warning-standard" class="is-solid is-warning warning-icon" size="14" [hidden]="!deletedLabelCount || !(filterListData[i]?.name=='label')"></clr-icon>
|
||||
<clr-icon shape="times-circle" class="is-solid" (click)="deleteFilter(i)"></clr-icon>
|
||||
<div *ngIf="!withAdmiral">
|
||||
<hbr-filter-label [projectId]="projectId" [selectedLabelInfo]="filterLabelInfo" [isOpen]="filterListData[i].isOpen" (selectedLabels)="selectedLabelList($event, i)"
|
||||
(closePanelEvent)="filterListData[i].isOpen = false"></hbr-filter-label>
|
||||
<div class="select inline-block" *ngIf="supportedFilters[i]?.style==='radio'">
|
||||
<select formControlName="value" #selectedValue id="{{i}}" name="{{supportedFilters[i]?.type}}">
|
||||
<option *ngFor="let value of supportedFilters[i]?.values;" value="{{value}}">{{value}}</option>
|
||||
</select>
|
||||
</div>
|
||||
<clr-icon *ngIf="i=== filters.length-1" shape="times-circle" class="is-solid" (click)="deleteFilter(i)"></clr-icon>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -113,7 +100,7 @@
|
||||
<div class="form-group form-group-override">
|
||||
<label class="form-group-label-override">{{'REPLICATION.DEST_NAMESPACE' | translate}}</label>
|
||||
<div class="form-select">
|
||||
<div class="select endpointSelect pull-left">
|
||||
<div class="endpointSelect pull-left">
|
||||
<input formControlName="dest_namespace" type="text" id="dest_namespace" pattern="^[a-z0-9]+(?:[._-][a-z0-9]+)*$" class="inputWidth"
|
||||
maxlength="255">
|
||||
</div>
|
||||
|
@ -1,5 +1,5 @@
|
||||
.select {
|
||||
width: 186px;
|
||||
width: 190px;
|
||||
}
|
||||
|
||||
.select .optionMore {
|
||||
@ -40,7 +40,7 @@ h4 {
|
||||
|
||||
.endpointSelect {
|
||||
width: 270px;
|
||||
margin-right: 20px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.filterSelect {
|
||||
@ -49,11 +49,11 @@ h4 {
|
||||
}
|
||||
|
||||
.filterSelect clr-icon {
|
||||
margin-left: 15px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.filterSelect label {
|
||||
width: 136px;
|
||||
width: 190px;
|
||||
}
|
||||
|
||||
.filterSelect label input {
|
||||
@ -70,7 +70,7 @@ h4 {
|
||||
|
||||
.floatSetPar {
|
||||
display: inline-block;
|
||||
width: 120px;
|
||||
width: 70px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
@ -229,6 +229,10 @@ clr-modal {
|
||||
width:315px;
|
||||
}
|
||||
|
||||
.mr-t-15 {
|
||||
margin-top: 15px;
|
||||
.mr-t-10 {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.inline-block {
|
||||
display: inline-block;
|
||||
}
|
@ -33,10 +33,7 @@ import {
|
||||
EndpointService,
|
||||
EndpointDefaultService
|
||||
} from "../service/endpoint.service";
|
||||
import {
|
||||
ProjectDefaultService,
|
||||
ProjectService
|
||||
} from "../service/project.service";
|
||||
|
||||
import { OperationService } from "../operation/operation.service";
|
||||
import {FilterLabelComponent} from "./filter-label.component";
|
||||
import {LabelService} from "../service/label.service";
|
||||
@ -233,7 +230,6 @@ describe("CreateEditRuleComponent (inline template)", () => {
|
||||
{ provide: SERVICE_CONFIG, useValue: config },
|
||||
{ provide: ReplicationService, useClass: ReplicationDefaultService },
|
||||
{ provide: EndpointService, useClass: EndpointDefaultService },
|
||||
{ provide: ProjectService, useClass: ProjectDefaultService },
|
||||
{ provide: JobLogService, useClass: JobLogDefaultService },
|
||||
{ provide: OperationService },
|
||||
{ provide: LabelService }
|
||||
@ -275,7 +271,6 @@ describe("CreateEditRuleComponent (inline template)", () => {
|
||||
|
||||
it("Should open creation modal and load endpoints", async(() => {
|
||||
fixture.detectChanges();
|
||||
compCreate.initAdapter("harbor");
|
||||
compCreate.openCreateEditRule();
|
||||
fixture.whenStable().then(() => {
|
||||
fixture.detectChanges();
|
||||
@ -291,7 +286,6 @@ describe("CreateEditRuleComponent (inline template)", () => {
|
||||
|
||||
it("Should open modal to edit replication rule", async(() => {
|
||||
fixture.detectChanges();
|
||||
compCreate.initAdapter("harbor");
|
||||
compCreate.openCreateEditRule(mockRule.id);
|
||||
fixture.whenStable().then(() => {
|
||||
fixture.detectChanges();
|
||||
|
@ -21,7 +21,7 @@ import {
|
||||
EventEmitter,
|
||||
Output
|
||||
} from "@angular/core";
|
||||
import { Filter, ReplicationRule, Endpoint, Label, Adapter } from "../service/interface";
|
||||
import { Filter, ReplicationRule, Endpoint, Adapter } from "../service/interface";
|
||||
import { Subject, Subscription } from "rxjs";
|
||||
import { debounceTime, distinctUntilChanged } from "rxjs/operators";
|
||||
import { FormArray, FormBuilder, FormGroup, Validators, FormControl } from "@angular/forms";
|
||||
@ -31,9 +31,6 @@ import { ReplicationService } from "../service/replication.service";
|
||||
import { ErrorHandler } from "../error-handler/error-handler";
|
||||
import { TranslateService } from "@ngx-translate/core";
|
||||
import { EndpointService } from "../service/endpoint.service";
|
||||
import { ProjectService } from "../service/project.service";
|
||||
import { Project } from "../project-policy-config/project";
|
||||
import { LabelState } from "../tag/tag.component";
|
||||
|
||||
const ONE_HOUR_SECONDS = 3600;
|
||||
const ONE_DAY_SECONDS: number = 24 * ONE_HOUR_SECONDS;
|
||||
@ -47,14 +44,10 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
||||
_localTime: Date = new Date();
|
||||
sourceList: Endpoint[] = [];
|
||||
targetList: Endpoint[] = [];
|
||||
projectList: Project[] = [];
|
||||
selectedProjectList: Project[] = [];
|
||||
isFilterHide = false;
|
||||
weeklySchedule: boolean;
|
||||
noProjectInfo = "";
|
||||
noEndpointInfo = "";
|
||||
isPushMode = true;
|
||||
noSelectedProject = true;
|
||||
noSelectedEndpoint = true;
|
||||
filterCount = 0;
|
||||
alertClosed = false;
|
||||
@ -63,7 +56,7 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
||||
SCHEDULED: "Scheduled",
|
||||
EVENT_BASED: "EventBased"
|
||||
};
|
||||
filterSelect: string[] = ["type", "repository", "tag", "label"];
|
||||
|
||||
ruleNameTooltip = "REPLICATION.NAME_TOOLTIP";
|
||||
headerTitle = "REPLICATION.ADD_POLICY";
|
||||
|
||||
@ -75,20 +68,12 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
||||
nameChecker: Subject<string> = new Subject<string>();
|
||||
firstClick = 0;
|
||||
policyId: number;
|
||||
labelInputVal = '';
|
||||
filterLabelInfo: Label[] = []; // store filter selected labels` id
|
||||
deletedLabelCount = 0;
|
||||
deletedLabelInfo: string;
|
||||
confirmSub: Subscription;
|
||||
ruleForm: FormGroup;
|
||||
formArrayLabel: FormArray;
|
||||
copyUpdateForm: ReplicationRule;
|
||||
cronString: string;
|
||||
supportedTriggers: string[];
|
||||
supportedFilters: Filter[];
|
||||
|
||||
@Input() projectId: number;
|
||||
@Input() projectName: string;
|
||||
@Input() withAdmiral: boolean;
|
||||
|
||||
@Output() goToRegistry = new EventEmitter<any>();
|
||||
@ -100,27 +85,17 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
||||
private repService: ReplicationService,
|
||||
private endpointService: EndpointService,
|
||||
private errorHandler: ErrorHandler,
|
||||
private proService: ProjectService,
|
||||
private translateService: TranslateService,
|
||||
private ref: ChangeDetectorRef
|
||||
) {
|
||||
this.createForm();
|
||||
}
|
||||
|
||||
baseFilterData(name: string, option: string[], state: boolean) {
|
||||
return {
|
||||
name: name,
|
||||
options: option,
|
||||
state: state,
|
||||
isValid: true,
|
||||
isOpen: false // label list
|
||||
};
|
||||
}
|
||||
|
||||
initAdapter(type: string): void {
|
||||
this.repService.getReplicationAdapter(type).subscribe(adapter => {
|
||||
this.supportedFilters = adapter.supported_resource_filters;
|
||||
this.supportedTriggers = adapter.supported_triggers;
|
||||
this.ruleForm.get("trigger").get("kind").setValue(this.supportedTriggers[0]);
|
||||
});
|
||||
}
|
||||
|
||||
@ -131,7 +106,6 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
||||
}, error => {
|
||||
this.errorHandler.error(error);
|
||||
});
|
||||
this.initAdapter("harbor");
|
||||
this.nameChecker
|
||||
.pipe(debounceTime(300))
|
||||
.pipe(distinctUntilChanged())
|
||||
@ -195,7 +169,6 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
createForm() {
|
||||
this.formArrayLabel = this.fb.array([]);
|
||||
this.ruleForm = this.fb.group({
|
||||
name: ["", Validators.required],
|
||||
description: "",
|
||||
@ -231,7 +204,7 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
||||
name: "",
|
||||
description: "",
|
||||
trigger: {
|
||||
kind: this.supportedTriggers[0],
|
||||
kind: '',
|
||||
schedule_param: {
|
||||
cron: ""
|
||||
}
|
||||
@ -239,6 +212,7 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
||||
deletion: false
|
||||
});
|
||||
this.setFilter([]);
|
||||
this.initAdapter("harbor");
|
||||
this.copyUpdateForm = clone(this.ruleForm.value);
|
||||
}
|
||||
|
||||
@ -252,11 +226,9 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
||||
deletion: rule.deletion
|
||||
});
|
||||
|
||||
this.noSelectedProject = false;
|
||||
this.noSelectedEndpoint = false;
|
||||
|
||||
if (rule.filters) {
|
||||
this.reOrganizeLabel(rule.filters);
|
||||
this.setFilter(rule.filters);
|
||||
this.updateFilter(rule.filters);
|
||||
}
|
||||
@ -266,45 +238,6 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
||||
setTimeout(() => clearInterval(hnd), 2000);
|
||||
}
|
||||
|
||||
// reorganize filter structure
|
||||
reOrganizeLabel(filterLabels: any[]): void {
|
||||
let count = 0;
|
||||
if (filterLabels.length) {
|
||||
this.filterLabelInfo = [];
|
||||
|
||||
let delLabel = '';
|
||||
filterLabels.forEach((data: any) => {
|
||||
if (data.kind === this.filterSelect[3]) {
|
||||
if (!data.value.deleted) {
|
||||
count++;
|
||||
this.filterLabelInfo.push(data.value);
|
||||
} else {
|
||||
this.deletedLabelCount++;
|
||||
delLabel += data.value.name + ',';
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.translateService.get('REPLICATION.DELETED_LABEL_INFO', {
|
||||
param: delLabel
|
||||
}).subscribe((res: string) => {
|
||||
this.deletedLabelInfo = res;
|
||||
this.alertClosed = false;
|
||||
});
|
||||
|
||||
// delete api return label info, replace with label count
|
||||
if (delLabel || count) {
|
||||
let len = filterLabels.length;
|
||||
for (let i = 0; i < len; i++) {
|
||||
let lab = filterLabels.find(data => data.kind === this.filterSelect[3]);
|
||||
if (lab) { filterLabels.splice(filterLabels.indexOf(lab), 1); }
|
||||
}
|
||||
filterLabels.push({ kind: 'label', value: count + ' labels' });
|
||||
this.labelInputVal = count.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
get filters(): FormArray {
|
||||
return this.ruleForm.get("filters") as FormArray;
|
||||
}
|
||||
@ -316,63 +249,11 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
||||
|
||||
initFilter(name: string) {
|
||||
return this.fb.group({
|
||||
kind: name,
|
||||
type: name,
|
||||
value: ''
|
||||
});
|
||||
}
|
||||
|
||||
filterChange($event: any, selectedValue: string) {
|
||||
if ($event && $event.target["value"]) {
|
||||
let id: number = $event.target.id;
|
||||
let name: string = $event.target.name;
|
||||
let value: string = $event.target["value"];
|
||||
|
||||
const controlArray = <FormArray>this.ruleForm.get('filters');
|
||||
this.filterListData.forEach((data, index) => {
|
||||
if (index === +id) {
|
||||
data.name = $event.target.name = value;
|
||||
} else {
|
||||
data.options.splice(data.options.indexOf(value), 1);
|
||||
}
|
||||
if (data.options.indexOf(name) === -1) {
|
||||
data.options.push(name);
|
||||
}
|
||||
|
||||
// if before select, $event is label
|
||||
if (!this.withAdmiral && name === this.filterSelect[3] && data.name === value) {
|
||||
this.labelInputVal = controlArray.controls[index].get('value').value.split(' ')[0];
|
||||
data.isOpen = false;
|
||||
controlArray.controls[index].get('value').setValue('');
|
||||
}
|
||||
// if before select, $event is not label
|
||||
if (!this.withAdmiral && data.name === this.filterSelect[2]) {
|
||||
if (this.labelInputVal) {
|
||||
controlArray.controls[index].get('value').setValue(this.labelInputVal + ' labels');
|
||||
} else {
|
||||
controlArray.controls[index].get('value').setValue('');
|
||||
}
|
||||
|
||||
// this.labelInputVal = '';
|
||||
data.isOpen = false;
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// when input value is label, then open label panel
|
||||
openLabelList(labelTag: string, indexId: number, $event: any) {
|
||||
if (!this.withAdmiral && labelTag === this.filterSelect[3]) {
|
||||
this.filterListData.forEach((data, index) => {
|
||||
if (index === indexId) {
|
||||
data.isOpen = true;
|
||||
} else {
|
||||
data.isOpen = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
targetChange($event: any) {
|
||||
if ($event && $event.target) {
|
||||
if ($event.target["value"] === "-1") {
|
||||
@ -392,10 +273,6 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
}
|
||||
|
||||
leaveInput() {
|
||||
this.selectedProjectList = [];
|
||||
}
|
||||
|
||||
addNewNamespace(): void {
|
||||
this.src_namespaces.push(new FormControl());
|
||||
}
|
||||
@ -403,65 +280,23 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
||||
deleteNamespace(index: number): void {
|
||||
this.src_namespaces.removeAt(index);
|
||||
}
|
||||
getCurrentIndex(): number {
|
||||
return this.filters.length;
|
||||
}
|
||||
|
||||
addNewFilter(): void {
|
||||
const controlArray = <FormArray>this.ruleForm.get('filters');
|
||||
if (this.filterCount === 0) {
|
||||
this.filterListData.push(
|
||||
this.baseFilterData(
|
||||
this.filterSelect[0],
|
||||
this.filterSelect.slice(),
|
||||
true,
|
||||
)
|
||||
);
|
||||
controlArray.push(this.initFilter(this.filterSelect[0]));
|
||||
} else {
|
||||
let nameArr: string[] = this.filterSelect.slice();
|
||||
this.filterListData.forEach(data => {
|
||||
nameArr.splice(nameArr.indexOf(data.name), 1);
|
||||
});
|
||||
// when add a new filter,the filterListData should change the options
|
||||
this.filterListData.filter(data => {
|
||||
data.options.splice(data.options.indexOf(nameArr[0]), 1);
|
||||
});
|
||||
this.filterListData.push(this.baseFilterData(nameArr[0], nameArr, true));
|
||||
controlArray.push(this.initFilter(nameArr[0]));
|
||||
}
|
||||
this.filterCount += 1;
|
||||
if (this.filterCount >= this.filterSelect.length) {
|
||||
let index = this.getCurrentIndex();
|
||||
this.filters.push(this.initFilter(this.supportedFilters[index].type));
|
||||
if (index + 1 >= this.supportedFilters.length) {
|
||||
this.isFilterHide = true;
|
||||
}
|
||||
if (controlArray.controls[this.filterCount - 1].get('kind').value === this.filterSelect[3] && this.labelInputVal) {
|
||||
controlArray.controls[this.filterCount - 1].get('value').setValue(this.labelInputVal + ' labels');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// delete a filter
|
||||
deleteFilter(i: number): void {
|
||||
if (i >= 0) {
|
||||
let delFilter = this.filterListData.splice(i, 1)[0];
|
||||
if (this.filterCount === this.filterSelect.length) {
|
||||
this.filters.removeAt(i);
|
||||
this.isFilterHide = false;
|
||||
}
|
||||
this.filterCount -= 1;
|
||||
if (this.filterListData.length) {
|
||||
let optionVal = delFilter.name;
|
||||
this.filterListData.filter(data => {
|
||||
if (data.options.indexOf(optionVal) === -1) {
|
||||
data.options.push(optionVal);
|
||||
}
|
||||
});
|
||||
}
|
||||
const control = <FormArray>this.ruleForm.get('filters');
|
||||
if (control.controls[i].get('kind').value === this.filterSelect[2]) {
|
||||
this.filterLabelInfo = [];
|
||||
this.labelInputVal = "";
|
||||
}
|
||||
control.removeAt(i);
|
||||
this.setFilter(control.value);
|
||||
}
|
||||
}
|
||||
|
||||
// Replication Schedule select value exchange
|
||||
selectSchedule($event: any): void {
|
||||
@ -478,57 +313,6 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
updateFilter(filters: any) {
|
||||
let opt: string[] = this.filterSelect.slice();
|
||||
filters.forEach((filter: any) => {
|
||||
opt.splice(opt.indexOf(filter.kind), 1);
|
||||
});
|
||||
filters.forEach((filter: any) => {
|
||||
let option: string[] = opt.slice();
|
||||
option.unshift(filter.kind);
|
||||
this.filterListData.push(this.baseFilterData(filter.kind, option, true));
|
||||
});
|
||||
this.filterCount = filters.length;
|
||||
if (filters.length === this.filterSelect.length) {
|
||||
this.isFilterHide = true;
|
||||
}
|
||||
}
|
||||
|
||||
selectedLabelList(selectedLabels: LabelState[], indexId: number) {
|
||||
// set input value of filter label
|
||||
const controlArray = <FormArray>this.ruleForm.get('filters');
|
||||
|
||||
this.filterListData.forEach((data, index) => {
|
||||
if (data.name === this.filterSelect[2]) {
|
||||
let labelsLength = selectedLabels.filter(lab => lab.iconsShow === true).length;
|
||||
if (labelsLength > 0) {
|
||||
controlArray.controls[index].get('value').setValue(labelsLength + ' labels');
|
||||
this.labelInputVal = labelsLength.toString();
|
||||
} else {
|
||||
controlArray.controls[index].get('value').setValue('');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// store filter label info
|
||||
this.filterLabelInfo = [];
|
||||
selectedLabels.forEach(data => {
|
||||
if (data.iconsShow === true) {
|
||||
this.filterLabelInfo.push(data.label);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
setFilterLabelVal(filters: any[]) {
|
||||
let labels: any = filters.find(data => data.kind === this.filterSelect[2]);
|
||||
|
||||
if (labels) {
|
||||
filters.splice(filters.indexOf(labels), 1);
|
||||
let info: any[] = [];
|
||||
this.filterLabelInfo.forEach(data => {
|
||||
info.push({ kind: 'label', value: data.id });
|
||||
});
|
||||
filters.push.apply(filters, info);
|
||||
}
|
||||
}
|
||||
|
||||
public hasFormChange(): boolean {
|
||||
@ -544,8 +328,6 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
||||
} else {
|
||||
copyRuleForm.dest_registry_id = null;
|
||||
}
|
||||
// rewrite key name of label when filer contain labels.
|
||||
if (copyRuleForm.filters) { this.setFilterLabelVal(copyRuleForm.filters); }
|
||||
|
||||
if (this.policyId < 0) {
|
||||
this.repService
|
||||
@ -581,30 +363,20 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
||||
openCreateEditRule(ruleId?: number | string): void {
|
||||
this.initForm();
|
||||
this.inlineAlert.close();
|
||||
this.selectedProjectList = [];
|
||||
this.filterCount = 0;
|
||||
this.isFilterHide = false;
|
||||
this.filterListData = [];
|
||||
this.firstClick = 0;
|
||||
this.noSelectedProject = true;
|
||||
this.noSelectedEndpoint = true;
|
||||
this.isRuleNameValid = true;
|
||||
this.deletedLabelCount = 0;
|
||||
|
||||
this.weeklySchedule = false;
|
||||
this.policyId = -1;
|
||||
this.createEditRuleOpened = true;
|
||||
this.filterLabelInfo = [];
|
||||
this.labelInputVal = '';
|
||||
|
||||
this.noProjectInfo = "";
|
||||
this.noEndpointInfo = "";
|
||||
if (this.targetList.length === 0) {
|
||||
this.noEndpointInfo = "REPLICATION.NO_ENDPOINT_INFO";
|
||||
}
|
||||
if (this.projectList.length === 0 && !this.projectName) {
|
||||
this.noProjectInfo = "REPLICATION.NO_PROJECT_INFO";
|
||||
}
|
||||
|
||||
if (ruleId) {
|
||||
this.policyId = +ruleId;
|
||||
@ -657,18 +429,6 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
||||
initValueCopy[key] = initValue[key];
|
||||
}
|
||||
|
||||
if (formValue.filters && formValue.filters.length > 0) {
|
||||
formValue.filters.forEach((data, index) => {
|
||||
if (data.kind === this.filterSelect[2]) {
|
||||
formValue.filters.splice(index, 1);
|
||||
}
|
||||
});
|
||||
// rewrite filter label
|
||||
this.filterLabelInfo.forEach(data => {
|
||||
formValue.filters.push({ kind: "label", pattern: "", value: data });
|
||||
});
|
||||
}
|
||||
|
||||
if (!compareValue(formValue, initValueCopy)) {
|
||||
return true;
|
||||
}
|
||||
|
@ -80,7 +80,7 @@
|
||||
</clr-datagrid>
|
||||
</div>
|
||||
</div>
|
||||
<hbr-create-edit-rule *ngIf="isSystemAdmin" [withAdmiral]="withAdmiral" [projectId]="projectId" [projectName]="projectName"
|
||||
<hbr-create-edit-rule *ngIf="isSystemAdmin" [withAdmiral]="withAdmiral"
|
||||
(goToRegistry)="goRegistry()" (reload)="reloadRules($event)"></hbr-create-edit-rule>
|
||||
<confirmation-dialog #replicationConfirmDialog (confirmAction)="confirmReplication($event)"></confirmation-dialog>
|
||||
<confirmation-dialog #StopConfirmDialog (confirmAction)="confirmStop($event)"></confirmation-dialog>
|
||||
|
@ -445,7 +445,6 @@
|
||||
"REPLICATE_IMMEDIATE": "Replicate existing images immediately",
|
||||
"NEW": "New",
|
||||
"NAME_TOOLTIP": "replication rule name should be at least 2 characters long with lower case characters, numbers and ._- and must be start with characters or numbers.",
|
||||
"DELETED_LABEL_INFO": "Deleted label(s) '{{param}}' referenced in the filter, click 'SAVE' to update the filter to enable this rule.",
|
||||
"ACKNOWLEDGE": "Acknowledge",
|
||||
"RULE_DISABLED": "This rule has been disabled because a label used in its filter has been deleted. \n Edit the rule and update its filter to enable it.",
|
||||
"REPLI_MODE": "Replication mode",
|
||||
|
@ -446,7 +446,6 @@
|
||||
"REPLICATE_IMMEDIATE": "Replicate existing images immediately",
|
||||
"NEW": "New",
|
||||
"NAME_TOOLTIP": "replication rule name should be at least 2 characters long with lower case characters, numbers and ._- and must be start with characters or numbers.",
|
||||
"DELETED_LABEL_INFO": "Deleted label(s) '{{param}}' referenced in the filter, click 'SAVE' to update the filter to enable this rule.",
|
||||
"ACKNOWLEDGE": "Acknowledge",
|
||||
"RULE_DISABLED": "This rule has been disabled because a label used in its filter has been deleted. \n Edit the rule and update its filter to enable it.",
|
||||
"REPLI_MODE": "Replication mode",
|
||||
|
@ -427,7 +427,6 @@
|
||||
"REPLICATE_IMMEDIATE": "Replicate existing images immediately",
|
||||
"NEW": "New",
|
||||
"NAME_TOOLTIP": "replication rule name should be at least 2 characters long with lower case characters, numbers and ._- and must be start with characters or numbers.",
|
||||
"DELETED_LABEL_INFO": "Deleted label(s) '{{param}}' referenced in the filter, click 'SAVE' to update the filter to enable this rule.",
|
||||
"ACKNOWLEDGE": "Acknowledge",
|
||||
"RULE_DISABLED": "This rule has been disabled because a label used in its filter has been deleted. \n Edit the rule and update its filter to enable it.",
|
||||
"REPLI_MODE": "Replication mode",
|
||||
|
@ -445,7 +445,6 @@
|
||||
"REPLICATE_IMMEDIATE":"Replicar imagens existentes imediatamente",
|
||||
"NEW": "Novo",
|
||||
"NAME_TOOLTIP": "nome da regra de replicação deve conter ao menos 2 caracteres sendo caracteres minusculos, números e ._- e devem iniciar com letras e números.",
|
||||
"DELETED_LABEL_INFO": "Removidas as label(s) '{{param}}' referenciadas no filtro, clique 'SALVAR' para atualizar o filtro e habilitar essa regra.",
|
||||
"ACKNOWLEDGE": "Reconhecer",
|
||||
"RULE_DISABLED": "Essa regra foi desabilitada pois uma label usada no seu filtro foi removida. \n Edite a regra e atualize seu filtro para habilitá-la.",
|
||||
"REPLI_MODE": "Replication mode",
|
||||
|
@ -446,7 +446,6 @@
|
||||
"REPLICATE_IMMEDIATE": "立即复制现有的镜像。",
|
||||
"NEW": "新增",
|
||||
"NAME_TOOLTIP": "项目名称由小写字符、数字和._-组成且至少2个字符并以字符或者数字开头。",
|
||||
"DELETED_LABEL_INFO": "过滤项有被删除的标签 {{param}} , 点击保存按钮更新过滤项使规则可用。",
|
||||
"ACKNOWLEDGE": "确认",
|
||||
"RULE_DISABLED": "这个规则因为过滤选项中的标签被删除已经不能用了,更新过滤项以便重新启用规则。",
|
||||
"REPLI_MODE": "复制模式",
|
||||
|
Loading…
Reference in New Issue
Block a user