mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-27 04:35:16 +01:00
Merge pull request #7282 from zhoumeina/replication_ng
modify frontend replication UI to apply api changes. use dest registry as object
This commit is contained in:
commit
3978def928
@ -33,8 +33,8 @@
|
|||||||
<label class="form-group-label-override required">{{'REPLICATION.SOURCE_REGISTRY' | translate}}</label>
|
<label class="form-group-label-override required">{{'REPLICATION.SOURCE_REGISTRY' | translate}}</label>
|
||||||
<div class="form-select">
|
<div class="form-select">
|
||||||
<div class="select endpointSelect pull-left">
|
<div class="select endpointSelect pull-left">
|
||||||
<select id="src_registry_id" (change)="sourceChange($event)" formControlName="src_registry_id">
|
<select id="src_registry_id" (change)="sourceChange($event)" formControlName="src_registry">
|
||||||
<option *ngFor="let source of sourceList" [ngValue]="source.id">{{source.name}}-{{source.url}}</option>
|
<option *ngFor="let source of sourceList" [ngValue]="source">{{source.name}}-{{source.url}}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -63,8 +63,8 @@
|
|||||||
<div formArrayName="filters">
|
<div formArrayName="filters">
|
||||||
<div class="filterSelect" *ngFor="let filter of filters.controls; let i=index">
|
<div class="filterSelect" *ngFor="let filter of filters.controls; let i=index">
|
||||||
<div [formGroupName]="i">
|
<div [formGroupName]="i">
|
||||||
<div class="floatSetPar">
|
<div class="width-70">
|
||||||
<label>{{supportedFilters[i].type}}:</label>
|
<label>{{"REPLICATION." + supportedFilters[i].type.toUpperCase() | translate}}:</label>
|
||||||
</div>
|
</div>
|
||||||
<label *ngIf="supportedFilters[i]?.style==='input'" aria-haspopup="true" role="tooltip" class="tooltip tooltip-validation tooltip-md tooltip-bottom-left"
|
<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'>
|
[class.invalid]='(filter.value.dirty || filter.value.touched) && filter.value.invalid'>
|
||||||
@ -88,8 +88,8 @@
|
|||||||
<label class="form-group-label-override required">{{'REPLICATION.DEST_REGISTRY' | translate}}</label>
|
<label class="form-group-label-override required">{{'REPLICATION.DEST_REGISTRY' | translate}}</label>
|
||||||
<div class="form-select">
|
<div class="form-select">
|
||||||
<div class="select endpointSelect pull-left">
|
<div class="select endpointSelect pull-left">
|
||||||
<select id="dest_registry_id" (change)="targetChange($event)" formControlName="dest_registry_id">
|
<select id="dest_registry_id" (change)="targetChange($event)" formControlName="dest_registry">
|
||||||
<option *ngFor="let target of targetList" [ngValue]="target.id">{{target.name}}-{{target.url}}</option>
|
<option *ngFor="let target of targetList" [ngValue]="target">{{target.name}}-{{target.url}}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -112,13 +112,13 @@
|
|||||||
<label class="form-group-label-override">{{'REPLICATION.TRIGGER_MODE' | translate}}</label>
|
<label class="form-group-label-override">{{'REPLICATION.TRIGGER_MODE' | translate}}</label>
|
||||||
<div formGroupName="trigger">
|
<div formGroupName="trigger">
|
||||||
<!--on trigger-->
|
<!--on trigger-->
|
||||||
<div class="select floatSetPar">
|
<div class="select width-115">
|
||||||
<select id="ruleTrigger" formControlName="kind" (change)="selectTrigger($event)">
|
<select id="ruleTrigger" formControlName="type" (change)="selectTrigger($event)">
|
||||||
<option *ngFor="let trigger of supportedTriggers" [value]="trigger">{{trigger }}</option>
|
<option *ngFor="let trigger of supportedTriggers" [value]="trigger">{{'REPLICATION.' + trigger.toUpperCase() | translate }}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<!--on push-->
|
<!--on push-->
|
||||||
<div formGroupName="schedule_param">
|
<div formGroupName="trigger_settings">
|
||||||
<div [hidden]="isNotSchedule()">
|
<div [hidden]="isNotSchedule()">
|
||||||
<label>Cron String</label>
|
<label>Cron String</label>
|
||||||
<label for="targetCron" aria-haspopup="true" role="tooltip" class="tooltip tooltip-validation tooltip-md tooltip-top-right">
|
<label for="targetCron" aria-haspopup="true" role="tooltip" class="tooltip tooltip-validation tooltip-md tooltip-top-right">
|
||||||
|
@ -68,12 +68,18 @@ h4 {
|
|||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.floatSetPar {
|
.width-70 {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 70px;
|
width: 70px;
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.width-115 {
|
||||||
|
display: inline-block;
|
||||||
|
width: 115px;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
.schedule-style {
|
.schedule-style {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
@ -166,7 +166,7 @@ describe("CreateEditRuleComponent (inline template)", () => {
|
|||||||
deletion: false
|
deletion: false
|
||||||
};
|
};
|
||||||
|
|
||||||
let mockAdapter = {
|
let mockRegistryInfo = {
|
||||||
"type": "harbor",
|
"type": "harbor",
|
||||||
"description": "",
|
"description": "",
|
||||||
"supported_resource_filters": [
|
"supported_resource_filters": [
|
||||||
@ -269,8 +269,8 @@ describe("CreateEditRuleComponent (inline template)", () => {
|
|||||||
spyJobs = spyOn(replicationService, "getExecutions").and.returnValues(
|
spyJobs = spyOn(replicationService, "getExecutions").and.returnValues(
|
||||||
of(mockJob));
|
of(mockJob));
|
||||||
|
|
||||||
spyAdapter = spyOn(replicationService, "getReplicationAdapter").and.returnValues(
|
spyAdapter = spyOn(replicationService, "getRegistryInfo").and.returnValues(
|
||||||
of(mockAdapter));
|
of(mockRegistryInfo));
|
||||||
spyEndpoint = spyOn(endpointService, "getEndpoints").and.returnValues(
|
spyEndpoint = spyOn(endpointService, "getEndpoints").and.returnValues(
|
||||||
of(mockEndpoints)
|
of(mockEndpoints)
|
||||||
);
|
);
|
||||||
|
@ -52,9 +52,9 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
|||||||
filterCount = 0;
|
filterCount = 0;
|
||||||
alertClosed = false;
|
alertClosed = false;
|
||||||
TRIGGER_TYPES = {
|
TRIGGER_TYPES = {
|
||||||
MANUAL: "Manual",
|
MANUAL: "manual",
|
||||||
SCHEDULED: "Scheduled",
|
SCHEDULED: "scheduled",
|
||||||
EVENT_BASED: "EventBased"
|
EVENT_BASED: "eventBased"
|
||||||
};
|
};
|
||||||
|
|
||||||
ruleNameTooltip = "REPLICATION.NAME_TOOLTIP";
|
ruleNameTooltip = "REPLICATION.NAME_TOOLTIP";
|
||||||
@ -91,11 +91,11 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
|||||||
this.createForm();
|
this.createForm();
|
||||||
}
|
}
|
||||||
|
|
||||||
initAdapter(type: string): void {
|
initRegistryInfo(id: number): void {
|
||||||
this.repService.getReplicationAdapter(type).subscribe(adapter => {
|
this.repService.getRegistryInfo(id).subscribe(adapter => {
|
||||||
this.supportedFilters = adapter.supported_resource_filters;
|
this.supportedFilters = adapter.supported_resource_filters;
|
||||||
this.supportedTriggers = adapter.supported_triggers;
|
this.supportedTriggers = adapter.supported_triggers;
|
||||||
this.ruleForm.get("trigger").get("kind").setValue(this.supportedTriggers[0]);
|
this.ruleForm.get("trigger").get("type").setValue(this.supportedTriggers[0]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,20 +134,15 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
modeChange(): void {
|
modeChange(): void {
|
||||||
if (this.isPushMode) {
|
if (this.isPushMode) {
|
||||||
this.initAdapter("harbor");
|
this.initRegistryInfo(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
sourceChange($event): void {
|
sourceChange($event): void {
|
||||||
this.noSelectedEndpoint = false;
|
this.noSelectedEndpoint = false;
|
||||||
let selectId = this.ruleForm.get('src_registry_id').value;
|
let selectId = this.ruleForm.get('src_registry').value;
|
||||||
let selecedTarget: Endpoint = this.sourceList.find(
|
this.initRegistryInfo(selectId.id);
|
||||||
source => source.id === selectId
|
|
||||||
);
|
|
||||||
|
|
||||||
this.initAdapter(selecedTarget.type);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy(): void {
|
ngOnDestroy(): void {
|
||||||
@ -172,13 +167,13 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
|||||||
this.ruleForm = this.fb.group({
|
this.ruleForm = this.fb.group({
|
||||||
name: ["", Validators.required],
|
name: ["", Validators.required],
|
||||||
description: "",
|
description: "",
|
||||||
src_registry_id: new FormControl(),
|
src_registry: new FormControl(),
|
||||||
src_namespaces: new FormArray([new FormControl('')], Validators.required),
|
src_namespaces: new FormArray([new FormControl('')], Validators.required),
|
||||||
dest_registry_id: new FormControl(),
|
dest_registry: new FormControl(),
|
||||||
dest_namespace: "",
|
dest_namespace: "",
|
||||||
trigger: this.fb.group({
|
trigger: this.fb.group({
|
||||||
kind: '',
|
type: '',
|
||||||
schedule_param: this.fb.group({
|
trigger_settings: this.fb.group({
|
||||||
cron: ""
|
cron: ""
|
||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
@ -192,11 +187,11 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
isNotSchedule(): boolean {
|
isNotSchedule(): boolean {
|
||||||
return this.ruleForm.get("trigger").get("kind").value !== this.TRIGGER_TYPES.SCHEDULED;
|
return this.ruleForm.get("trigger").get("type").value !== this.TRIGGER_TYPES.SCHEDULED;
|
||||||
}
|
}
|
||||||
|
|
||||||
isNotEventBased(): boolean {
|
isNotEventBased(): boolean {
|
||||||
return this.ruleForm.get("trigger").get("kind").value !== this.TRIGGER_TYPES.EVENT_BASED;
|
return this.ruleForm.get("trigger").get("type").value !== this.TRIGGER_TYPES.EVENT_BASED;
|
||||||
}
|
}
|
||||||
|
|
||||||
initForm(): void {
|
initForm(): void {
|
||||||
@ -204,15 +199,15 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
|||||||
name: "",
|
name: "",
|
||||||
description: "",
|
description: "",
|
||||||
trigger: {
|
trigger: {
|
||||||
kind: '',
|
type: '',
|
||||||
schedule_param: {
|
trigger_settings: {
|
||||||
cron: ""
|
cron: ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
deletion: false
|
deletion: false
|
||||||
});
|
});
|
||||||
this.setFilter([]);
|
this.setFilter([]);
|
||||||
this.initAdapter("harbor");
|
this.initRegistryInfo(0);
|
||||||
this.copyUpdateForm = clone(this.ruleForm.value);
|
this.copyUpdateForm = clone(this.ruleForm.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -324,9 +319,9 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
|
|||||||
this.inProgress = true;
|
this.inProgress = true;
|
||||||
let copyRuleForm: ReplicationRule = this.ruleForm.value;
|
let copyRuleForm: ReplicationRule = this.ruleForm.value;
|
||||||
if (this.isPushMode) {
|
if (this.isPushMode) {
|
||||||
copyRuleForm.src_registry_id = null;
|
copyRuleForm.src_registry = null;
|
||||||
} else {
|
} else {
|
||||||
copyRuleForm.dest_registry_id = null;
|
copyRuleForm.dest_registry = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.policyId < 0) {
|
if (this.policyId < 0) {
|
||||||
|
@ -79,6 +79,7 @@ import { OperationService } from './operation/operation.service';
|
|||||||
* this default configuration.
|
* this default configuration.
|
||||||
*/
|
*/
|
||||||
export const DefaultServiceConfig: IServiceConfig = {
|
export const DefaultServiceConfig: IServiceConfig = {
|
||||||
|
baseEndpoint: "/api",
|
||||||
systemInfoEndpoint: "/api/systeminfo",
|
systemInfoEndpoint: "/api/systeminfo",
|
||||||
repositoryBaseEndpoint: "/api/repositories",
|
repositoryBaseEndpoint: "/api/repositories",
|
||||||
logBaseEndpoint: "/api/logs",
|
logBaseEndpoint: "/api/logs",
|
||||||
|
@ -2,6 +2,7 @@ import { InjectionToken } from '@angular/core';
|
|||||||
|
|
||||||
export let SERVICE_CONFIG = new InjectionToken("service.config");
|
export let SERVICE_CONFIG = new InjectionToken("service.config");
|
||||||
export interface IServiceConfig {
|
export interface IServiceConfig {
|
||||||
|
baseEndpoint?: string;
|
||||||
/**
|
/**
|
||||||
* The base endpoint of service used to retrieve the system configuration information.
|
* The base endpoint of service used to retrieve the system configuration information.
|
||||||
* The configurations may include but not limit:
|
* The configurations may include but not limit:
|
||||||
|
@ -141,7 +141,7 @@ export abstract class ReplicationService {
|
|||||||
): Observable<any>;
|
): Observable<any>;
|
||||||
|
|
||||||
|
|
||||||
abstract getReplicationAdapter(type: string): Observable<any>;
|
abstract getRegistryInfo(id: number): Observable<any>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the jobs for the specified replication rule.
|
* Get the jobs for the specified replication rule.
|
||||||
@ -207,6 +207,7 @@ export abstract class ReplicationService {
|
|||||||
export class ReplicationDefaultService extends ReplicationService {
|
export class ReplicationDefaultService extends ReplicationService {
|
||||||
_ruleBaseUrl: string;
|
_ruleBaseUrl: string;
|
||||||
_replicateUrl: string;
|
_replicateUrl: string;
|
||||||
|
_baseUrl: string;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private http: Http,
|
private http: Http,
|
||||||
@ -219,6 +220,7 @@ export class ReplicationDefaultService extends ReplicationService {
|
|||||||
this._replicateUrl = config.replicationBaseEndpoint
|
this._replicateUrl = config.replicationBaseEndpoint
|
||||||
? config.replicationBaseEndpoint
|
? config.replicationBaseEndpoint
|
||||||
: "/api/replication";
|
: "/api/replication";
|
||||||
|
this._baseUrl = config.baseEndpoint ? config.baseEndpoint : "/api";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Private methods
|
// Private methods
|
||||||
@ -230,12 +232,12 @@ export class ReplicationDefaultService extends ReplicationService {
|
|||||||
rule.name !== undefined &&
|
rule.name !== undefined &&
|
||||||
rule.name.trim() !== "" &&
|
rule.name.trim() !== "" &&
|
||||||
rule.src_namespaces && rule.src_namespaces.length > 0 &&
|
rule.src_namespaces && rule.src_namespaces.length > 0 &&
|
||||||
(!!rule.dest_registry_id || !!rule.src_registry_id)
|
(!!rule.dest_registry || !!rule.src_registry)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public getReplicationAdapter(type): Observable<any> {
|
public getRegistryInfo(id): Observable<any> {
|
||||||
let requestUrl: string = `${this._replicateUrl}/adapters/${type}`;
|
let requestUrl: string = `${this._baseUrl}/registries/${id}/info`;
|
||||||
return this.http
|
return this.http
|
||||||
.get(requestUrl)
|
.get(requestUrl)
|
||||||
.pipe(map(response => response.json())
|
.pipe(map(response => response.json())
|
||||||
|
@ -432,9 +432,9 @@
|
|||||||
"NO_ENDPOINT_INFO": "Please add an endpoint first",
|
"NO_ENDPOINT_INFO": "Please add an endpoint first",
|
||||||
"NO_PROJECT_INFO": "This project is not exist",
|
"NO_PROJECT_INFO": "This project is not exist",
|
||||||
"SOURCE_IMAGES_FILTER": "Source images filter",
|
"SOURCE_IMAGES_FILTER": "Source images filter",
|
||||||
"SCHEDULE": "Scheduled",
|
"SCHEDULED": "Scheduled",
|
||||||
"MANUAL": "Manual",
|
"MANUAL": "Manual",
|
||||||
"IMMEDIATE": "Immediate",
|
"EVENT_BASED":"Event Based",
|
||||||
"DAILY": "Daily",
|
"DAILY": "Daily",
|
||||||
"WEEKLY": "Weekly",
|
"WEEKLY": "Weekly",
|
||||||
"SETTING": "Options",
|
"SETTING": "Options",
|
||||||
@ -455,7 +455,10 @@
|
|||||||
"SOURCE_NAMESPACES":"Source namespaces",
|
"SOURCE_NAMESPACES":"Source namespaces",
|
||||||
"DEST_REGISTRY":"Destination registry",
|
"DEST_REGISTRY":"Destination registry",
|
||||||
"DEST_NAMESPACE":"Destination namespace",
|
"DEST_NAMESPACE":"Destination namespace",
|
||||||
"NAMESPACE_TOOLTIP": "Namespace name should be at least 2 characters long with lower case characters, numbers and ._- and must be start with characters or numbers."
|
"NAMESPACE_TOOLTIP": "Namespace name should be at least 2 characters long with lower case characters, numbers and ._- and must be start with characters or numbers.",
|
||||||
|
"TAG":"Tag",
|
||||||
|
"LABEL":"Label",
|
||||||
|
"RESOURCE":"Resource"
|
||||||
},
|
},
|
||||||
"DESTINATION": {
|
"DESTINATION": {
|
||||||
"NEW_ENDPOINT": "New Endpoint",
|
"NEW_ENDPOINT": "New Endpoint",
|
||||||
|
@ -433,9 +433,9 @@
|
|||||||
"NO_ENDPOINT_INFO": "Please add an endpoint first",
|
"NO_ENDPOINT_INFO": "Please add an endpoint first",
|
||||||
"NO_PROJECT_INFO": "This project is not exist",
|
"NO_PROJECT_INFO": "This project is not exist",
|
||||||
"SOURCE_IMAGES_FILTER": "Source images filter",
|
"SOURCE_IMAGES_FILTER": "Source images filter",
|
||||||
"SCHEDULE": "Scheduled",
|
"SCHEDULED": "Scheduled",
|
||||||
"MANUAL": "Manual",
|
"MANUAL": "Manual",
|
||||||
"IMMEDIATE": "Immediate",
|
"EVENT_BASED":"Event Based",
|
||||||
"DAILY": "Daily",
|
"DAILY": "Daily",
|
||||||
"WEEKLY": "Weekly",
|
"WEEKLY": "Weekly",
|
||||||
"SETTING": "Options",
|
"SETTING": "Options",
|
||||||
@ -456,7 +456,10 @@
|
|||||||
"SOURCE_NAMESPACES":"Source namespaces",
|
"SOURCE_NAMESPACES":"Source namespaces",
|
||||||
"DEST_REGISTRY":"Destination registry",
|
"DEST_REGISTRY":"Destination registry",
|
||||||
"DEST_NAMESPACE":"Destination namespace",
|
"DEST_NAMESPACE":"Destination namespace",
|
||||||
"NAMESPACE_TOOLTIP": "Namespace name should be at least 2 characters long with lower case characters, numbers and ._- and must be start with characters or numbers."
|
"NAMESPACE_TOOLTIP": "Namespace name should be at least 2 characters long with lower case characters, numbers and ._- and must be start with characters or numbers.",
|
||||||
|
"TAG":"Tag",
|
||||||
|
"LABEL":"Label",
|
||||||
|
"RESOURCE":"Resource"
|
||||||
},
|
},
|
||||||
"DESTINATION": {
|
"DESTINATION": {
|
||||||
"NEW_ENDPOINT": "Nuevo Endpoint",
|
"NEW_ENDPOINT": "Nuevo Endpoint",
|
||||||
|
@ -414,9 +414,9 @@
|
|||||||
"NO_ENDPOINT_INFO": "Please add an endpoint first",
|
"NO_ENDPOINT_INFO": "Please add an endpoint first",
|
||||||
"NO_PROJECT_INFO": "This project is not exist",
|
"NO_PROJECT_INFO": "This project is not exist",
|
||||||
"SOURCE_IMAGES_FILTER": "Source images filter",
|
"SOURCE_IMAGES_FILTER": "Source images filter",
|
||||||
"SCHEDULE": "Scheduled",
|
"SCHEDULED": "Scheduled",
|
||||||
"MANUAL": "Manual",
|
"MANUAL": "Manual",
|
||||||
"IMMEDIATE": "Immediate",
|
"EVENT_BASED":"Event Based",
|
||||||
"DAILY": "Daily",
|
"DAILY": "Daily",
|
||||||
"WEEKLY": "Weekly",
|
"WEEKLY": "Weekly",
|
||||||
"SETTING": "Options",
|
"SETTING": "Options",
|
||||||
@ -437,7 +437,10 @@
|
|||||||
"SOURCE_NAMESPACES":"Source namespaces",
|
"SOURCE_NAMESPACES":"Source namespaces",
|
||||||
"DEST_REGISTRY":"Destination registry",
|
"DEST_REGISTRY":"Destination registry",
|
||||||
"DEST_NAMESPACE":"Destination namespace",
|
"DEST_NAMESPACE":"Destination namespace",
|
||||||
"NAMESPACE_TOOLTIP": "Namespace name should be at least 2 characters long with lower case characters, numbers and ._- and must be start with characters or numbers."
|
"NAMESPACE_TOOLTIP": "Namespace name should be at least 2 characters long with lower case characters, numbers and ._- and must be start with characters or numbers.",
|
||||||
|
"TAG":"Tag",
|
||||||
|
"LABEL":"Label",
|
||||||
|
"RESOURCE":"Resource"
|
||||||
},
|
},
|
||||||
"DESTINATION": {
|
"DESTINATION": {
|
||||||
"NEW_ENDPOINT": "Nouveau Point Final",
|
"NEW_ENDPOINT": "Nouveau Point Final",
|
||||||
|
@ -432,9 +432,9 @@
|
|||||||
"NO_ENDPOINT_INFO": "Por favor adicione antes um endpoint",
|
"NO_ENDPOINT_INFO": "Por favor adicione antes um endpoint",
|
||||||
"NO_PROJECT_INFO": "Esse projeto não existe",
|
"NO_PROJECT_INFO": "Esse projeto não existe",
|
||||||
"SOURCE_IMAGES_FILTER": "Filtro de imagens de origem",
|
"SOURCE_IMAGES_FILTER": "Filtro de imagens de origem",
|
||||||
"SCHEDULE": "Agendado",
|
"SCHEDULED": "Agendado",
|
||||||
"MANUAL": "Manual",
|
"MANUAL": "Manual",
|
||||||
"IMMEDIATE": "Imediato",
|
"EVENT_BASED":"Event Based",
|
||||||
"DAILY": "Diário",
|
"DAILY": "Diário",
|
||||||
"WEEKLY": "Semanal",
|
"WEEKLY": "Semanal",
|
||||||
"SETTING":"Opções",
|
"SETTING":"Opções",
|
||||||
@ -455,7 +455,10 @@
|
|||||||
"SOURCE_NAMESPACES":"Source namespaces",
|
"SOURCE_NAMESPACES":"Source namespaces",
|
||||||
"DEST_REGISTRY":"Destination registry",
|
"DEST_REGISTRY":"Destination registry",
|
||||||
"DEST_NAMESPACE":"Destination namespace",
|
"DEST_NAMESPACE":"Destination namespace",
|
||||||
"NAMESPACE_TOOLTIP": "Namespace name should be at least 2 characters long with lower case characters, numbers and ._- and must be start with characters or numbers."
|
"NAMESPACE_TOOLTIP": "Namespace name should be at least 2 characters long with lower case characters, numbers and ._- and must be start with characters or numbers.",
|
||||||
|
"TAG":"Tag",
|
||||||
|
"LABEL":"Label",
|
||||||
|
"RESOURCE":"Resource"
|
||||||
},
|
},
|
||||||
"DESTINATION": {
|
"DESTINATION": {
|
||||||
"NEW_ENDPOINT": "Novo Endpoint",
|
"NEW_ENDPOINT": "Novo Endpoint",
|
||||||
|
@ -433,9 +433,9 @@
|
|||||||
"NO_ENDPOINT_INFO": "请先添加一个目标",
|
"NO_ENDPOINT_INFO": "请先添加一个目标",
|
||||||
"NO_PROJECT_INFO": "此项目不存在",
|
"NO_PROJECT_INFO": "此项目不存在",
|
||||||
"SOURCE_IMAGES_FILTER": "源镜像过滤器",
|
"SOURCE_IMAGES_FILTER": "源镜像过滤器",
|
||||||
"SCHEDULE": "定时",
|
"SCHEDULED": "定时",
|
||||||
"MANUAL": "手动",
|
"MANUAL": "手动",
|
||||||
"IMMEDIATE": "即刻",
|
"EVENT_BASED":"事件驱动",
|
||||||
"DAILY": "每天",
|
"DAILY": "每天",
|
||||||
"WEEKLY": "每周",
|
"WEEKLY": "每周",
|
||||||
"SETTING": "设置",
|
"SETTING": "设置",
|
||||||
@ -456,7 +456,10 @@
|
|||||||
"SOURCE_NAMESPACES":"源Namespace",
|
"SOURCE_NAMESPACES":"源Namespace",
|
||||||
"DEST_REGISTRY":"目的Registry",
|
"DEST_REGISTRY":"目的Registry",
|
||||||
"DEST_NAMESPACE":"目的Namespace",
|
"DEST_NAMESPACE":"目的Namespace",
|
||||||
"NAMESPACE_TOOLTIP": "Namespace名称由小写字符、数字和._-组成且至少2个字符并以字符或者数字开头。"
|
"NAMESPACE_TOOLTIP": "Namespace名称由小写字符、数字和._-组成且至少2个字符并以字符或者数字开头。",
|
||||||
|
"TAG":"Tag",
|
||||||
|
"LABEL":"标签",
|
||||||
|
"RESOURCE":"资源"
|
||||||
},
|
},
|
||||||
"DESTINATION": {
|
"DESTINATION": {
|
||||||
"NEW_ENDPOINT": "新建目标",
|
"NEW_ENDPOINT": "新建目标",
|
||||||
|
Loading…
Reference in New Issue
Block a user