Fix replication frontend issues

Signed-off-by: FangyuanCheng <fangyuanc@vmware.com>
This commit is contained in:
FangyuanCheng 2019-04-15 21:41:52 +08:00
parent 7729bca23b
commit 609f6cbda2
20 changed files with 128 additions and 52 deletions

View File

@ -257,10 +257,7 @@ export class CreateEditEndpointComponent
}, },
error => { error => {
this.onGoing = false; this.onGoing = false;
let errorMessageKey = this.handleErrorMessageKey(error.status); this.inlineAlert.showInlineError(error);
this.translateService.get(errorMessageKey).subscribe(res => {
this.inlineAlert.showInlineError(res);
});
this.forceRefreshView(2000); this.forceRefreshView(2000);
} }
); );
@ -302,27 +299,13 @@ export class CreateEditEndpointComponent
this.forceRefreshView(2000); this.forceRefreshView(2000);
}, },
error => { error => {
let errorMessageKey = this.handleErrorMessageKey(error.status); this.inlineAlert.showInlineError(error);
this.translateService.get(errorMessageKey).subscribe(res => {
this.inlineAlert.showInlineError(res);
});
this.onGoing = false; this.onGoing = false;
this.forceRefreshView(2000); this.forceRefreshView(2000);
} }
); );
} }
handleErrorMessageKey(status: number): string {
switch (status) {
case 409:
return "DESTINATION.CONFLICT_NAME";
case 400:
return "DESTINATION.INVALID_NAME";
default:
return "UNKNOWN_ERROR";
}
}
onCancel() { onCancel() {
let changes: { [key: string]: any } = this.getChanges(); let changes: { [key: string]: any } = this.getChanges();
if (!isEmptyObject(changes)) { if (!isEmptyObject(changes)) {

View File

@ -133,12 +133,18 @@
<label for="ruleDeletion" class="clr-control-label">{{'REPLICATION.DELETE_REMOTE_IMAGES' | translate}}</label> <label for="ruleDeletion" class="clr-control-label">{{'REPLICATION.DELETE_REMOTE_IMAGES' | translate}}</label>
</clr-checkbox-wrapper> </clr-checkbox-wrapper>
</div> </div>
<div class="clr-form-control rule-width"> <div class="rule-width">
<clr-checkbox-wrapper> <clr-checkbox-wrapper>
<input type="checkbox" clrCheckbox [checked]="true" id="enablePolicy" formControlName="enabled" class="clr-checkbox"> <input type="checkbox" clrCheckbox [checked]="true" id="enablePolicy" formControlName="enabled" class="clr-checkbox">
<label for="enablePolicy" class="clr-control-label">{{'REPLICATION.ENABLED' | translate}}</label> <label for="enablePolicy" class="clr-control-label">{{'REPLICATION.ENABLED' | translate}}</label>
</clr-checkbox-wrapper> </clr-checkbox-wrapper>
</div> </div>
<div class="rule-width">
<clr-checkbox-wrapper>
<input type="checkbox" clrCheckbox [checked]="true" id="overridePolicy" formControlName="override" class="clr-checkbox">
<label for="overridePolicy" class="clr-control-label">{{'REPLICATION.OVERRIDE' | translate}}</label>
</clr-checkbox-wrapper>
</div>
</div> </div>
<div class="loading-center"> <div class="loading-center">
<span class="spinner spinner-inline" [hidden]="inProgress === false"></span> <span class="spinner spinner-inline" [hidden]="inProgress === false"></span>

View File

@ -54,7 +54,8 @@ describe("CreateEditRuleComponent (inline template)", () => {
}, },
filters: [], filters: [],
deletion: false, deletion: false,
enabled: true enabled: true,
override: true
} }
]; ];
let mockJobs: ReplicationJobItem[] = [ let mockJobs: ReplicationJobItem[] = [
@ -166,7 +167,8 @@ describe("CreateEditRuleComponent (inline template)", () => {
}, },
filters: [], filters: [],
deletion: false, deletion: false,
enabled: true enabled: true,
override: true
}; };
let mockRegistryInfo = { let mockRegistryInfo = {

View File

@ -191,7 +191,8 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
}), }),
filters: this.fb.array([]), filters: this.fb.array([]),
deletion: false, deletion: false,
enabled: true enabled: true,
override: true
}); });
} }
@ -218,7 +219,8 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
} }
}, },
deletion: false, deletion: false,
enabled: true enabled: true,
override: true
}); });
this.isPushMode = true; this.isPushMode = true;
} }
@ -236,6 +238,7 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
} else { } else {
this.isPushMode = true; this.isPushMode = true;
} }
setTimeout(() => { setTimeout(() => {
this.ruleForm.reset({ this.ruleForm.reset({
name: rule.name, name: rule.name,
@ -246,7 +249,8 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
dest_registry: rule.dest_registry, dest_registry: rule.dest_registry,
trigger: rule.trigger, trigger: rule.trigger,
deletion: rule.deletion, deletion: rule.deletion,
enabled: rule.enabled enabled: rule.enabled,
override: rule.override
}); });
// reset the filter list. // reset the filter list.
let filters = []; let filters = [];
@ -260,7 +264,6 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
} }
}); });
} }
if (!findTag) { if (!findTag) {
filters.push({ type: this.supportedFilters[i].type, value: "" }); filters.push({ type: this.supportedFilters[i].type, value: "" });
} }

View File

@ -118,7 +118,6 @@ export class EndpointComponent implements OnInit, OnDestroy {
this.endpointService.getEndpoints(this.targetName) this.endpointService.getEndpoints(this.targetName)
.subscribe(targets => { .subscribe(targets => {
this.targets = targets || []; this.targets = targets || [];
this.forceRefreshView(1000);
this.loading = false; this.loading = false;
}, error => { }, error => {
this.errorHandler.error(error); this.errorHandler.error(error);

View File

@ -8,10 +8,10 @@
</clr-dg-action-bar> </clr-dg-action-bar>
<clr-dg-column>{{'REPLICATION.NAME' | translate}}</clr-dg-column> <clr-dg-column>{{'REPLICATION.NAME' | translate}}</clr-dg-column>
<clr-dg-column [clrDgField]="'status'" class="status-width">{{'REPLICATION.STATUS' | translate}}</clr-dg-column> <clr-dg-column [clrDgField]="'status'" class="status-width">{{'REPLICATION.STATUS' | translate}}</clr-dg-column>
<clr-dg-column class="min-width">{{'REPLICATION.SRC_NAMESPACE' | translate}}</clr-dg-column> <clr-dg-column class="min-width">{{'REPLICATION.SRC_REGISTRY' | translate}}</clr-dg-column>
<clr-dg-column>{{'REPLICATION.REPLICATION_MODE' | translate}}</clr-dg-column>
<clr-dg-column class="min-width">{{'REPLICATION.DESTINATION_NAMESPACE' | translate}}</clr-dg-column> <clr-dg-column class="min-width">{{'REPLICATION.DESTINATION_NAMESPACE' | translate}}</clr-dg-column>
<clr-dg-column [clrDgField]="'trigger'">{{'REPLICATION.REPLICATION_TRIGGER' | translate}}</clr-dg-column> <clr-dg-column [clrDgField]="'trigger'">{{'REPLICATION.REPLICATION_TRIGGER' | translate}}</clr-dg-column>
<clr-dg-column [clrDgField]="'override'" class="status-width">{{'REPLICATION.OVERRIDE' | translate}}</clr-dg-column>
<clr-dg-column [clrDgField]="'description'">{{'REPLICATION.DESCRIPTION' | translate}}</clr-dg-column> <clr-dg-column [clrDgField]="'description'">{{'REPLICATION.DESCRIPTION' | translate}}</clr-dg-column>
<clr-dg-placeholder>{{'REPLICATION.PLACEHOLDER' | translate }}</clr-dg-placeholder> <clr-dg-placeholder>{{'REPLICATION.PLACEHOLDER' | translate }}</clr-dg-placeholder>
<clr-dg-row *clrDgItems="let p of changedRules; let i=index" [clrDgItem]="p" [style.backgroundColor]="(projectScope && withReplicationJob && selectedId === p.id) ? '#eee' : ''"> <clr-dg-row *clrDgItems="let p of changedRules; let i=index" [clrDgItem]="p" [style.backgroundColor]="(projectScope && withReplicationJob && selectedId === p.id) ? '#eee' : ''">
@ -28,7 +28,7 @@
</div> </div>
</clr-dg-cell> </clr-dg-cell>
<clr-dg-cell class="min-width"> <clr-dg-cell class="min-width">
{{p.src_registry ? p.src_registry.name : ''}} : {{p.src_namespaces?.length>0 ? p.src_namespaces[0]: ''}} {{p.src_registry ? p.src_registry.name : ''}}
<clr-tooltip> <clr-tooltip>
<clr-icon *ngIf="p.src_namespaces && p.src_namespaces.length > 1" clrTooltipTrigger shape="ellipsis-horizontal" size="18"></clr-icon> <clr-icon *ngIf="p.src_namespaces && p.src_namespaces.length > 1" clrTooltipTrigger shape="ellipsis-horizontal" size="18"></clr-icon>
<clr-tooltip-content clrPosition="top-right" clrSize="md" *clrIfOpen> <clr-tooltip-content clrPosition="top-right" clrSize="md" *clrIfOpen>
@ -36,13 +36,14 @@
</clr-tooltip-content> </clr-tooltip-content>
</clr-tooltip> </clr-tooltip>
</clr-dg-cell> </clr-dg-cell>
<clr-dg-cell>
{{p.src_registry && p.src_registry.id > 0 ? 'pull-based' : 'push-based'}}
</clr-dg-cell>
<clr-dg-cell class="min-width"> <clr-dg-cell class="min-width">
{{p.dest_registry ? p.dest_registry.name : ''}} : {{p.dest_namespace? p.dest_namespace: '-'}} {{p.dest_registry ? p.dest_registry.name : ''}} : {{p.dest_namespace? p.dest_namespace: '-'}}
</clr-dg-cell> </clr-dg-cell>
<clr-dg-cell>{{p.trigger ? p.trigger.type : ''}}</clr-dg-cell> <clr-dg-cell>{{p.trigger ? p.trigger.type : ''}}</clr-dg-cell>
<clr-dg-cell [ngSwitch]="p.override">
<clr-icon shape="check-circle" *ngSwitchCase="true" size="20" class="color-green"></clr-icon>
<clr-icon shape="times-circle" *ngSwitchCase="false" size="16" class="icon-style"></clr-icon>
</clr-dg-cell>
<clr-dg-cell> <clr-dg-cell>
{{p.description ? trancatedDescription(p.description) : '-'}} {{p.description ? trancatedDescription(p.description) : '-'}}
<clr-tooltip> <clr-tooltip>

View File

@ -11,3 +11,7 @@
.status-width { .status-width {
width: 105px; width: 105px;
} }
.icon-style {
color: #C92100;
}

View File

@ -29,7 +29,8 @@ describe('ListReplicationRuleComponent (inline template)', () => {
"deletion": false, "deletion": false,
"src_namespaces": ["name1", "name2"], "src_namespaces": ["name1", "name2"],
"src_registry": {id: 3}, "src_registry": {id: 3},
"enabled": true "enabled": true,
"override": true
}, },
{ {
"id": 2, "id": 2,
@ -41,7 +42,8 @@ describe('ListReplicationRuleComponent (inline template)', () => {
"deletion": false, "deletion": false,
"src_namespaces": ["name1", "name2"], "src_namespaces": ["name1", "name2"],
"dest_registry": {id: 3}, "dest_registry": {id: 3},
"enabled": true "enabled": true,
"override": true
}, },
]; ];

View File

@ -49,17 +49,25 @@
<div class="flex-block"> <div class="flex-block">
<section class="execution-detail-label"> <section class="execution-detail-label">
<section class="detail-row"> <section class="detail-row">
<span class="label label-purple detail-span">{{'REPLICATION.SUCCESS'| translate}}</span> <div class="num-success common-style"></div>
<label class="detail-span">{{'REPLICATION.SUCCESS'| translate}}</label>
<div class="execution-details">{{successNum}}</div> <div class="execution-details">{{successNum}}</div>
</section> </section>
<section class="detail-row"> <section class="detail-row">
<span class="label label-red detail-span">{{'REPLICATION.FAILURE'| translate}}</span> <div class="num-failed common-style"></div>
<label class="detail-span">{{'REPLICATION.FAILURE'| translate}}</label>
<div class="execution-details">{{failedNum}}</div> <div class="execution-details">{{failedNum}}</div>
</section> </section>
<section class="detail-row"> <section class="detail-row">
<span class="label label-light-blue detail-span">{{'REPLICATION.IN_PROGRESS'| translate}}</span> <div class="num-progress common-style"></div>
<label class="detail-span">{{'REPLICATION.IN_PROGRESS'| translate}}</label>
<div class="execution-details">{{progressNum}}</div> <div class="execution-details">{{progressNum}}</div>
</section> </section>
<section class="detail-row">
<div class="num-stopped common-style"></div>
<label class="detail-span">{{'REPLICATION.STOPPED'| translate}}</label>
<div class="execution-details">{{stoppedNum}}</div>
</section>
</section> </section>
</div> </div>
</div> </div>

View File

@ -41,9 +41,27 @@
text-align: left; text-align: left;
.detail-row { .detail-row {
display: flex; display: flex;
height: 27px;
.common-style {
width: 12px;
height: 12px;
margin-top: 16px;
}
.num-success {
background-color: #308700;
}
.num-failed {
background-color: #C92101;
}
.num-progress {
background-color: #1C5898;
}
.num-stopped {
background-color: #A1A1A1;
}
.detail-span { .detail-span {
flex:0 0 100px; flex:0 0 100px;
margin-top: 10px; margin: 10px 0 0 10px;
} }
.execution-details { .execution-details {
width: 200px; width: 200px;

View File

@ -1,18 +1,20 @@
import { Component, OnInit, Input } from '@angular/core'; import { Component, OnInit, Input, OnDestroy } from '@angular/core';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { ReplicationService } from "../../service/replication.service"; import { ReplicationService } from "../../service/replication.service";
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { finalize } from "rxjs/operators"; import { finalize } from "rxjs/operators";
import { Subscription, timer } from "rxjs";
import { ErrorHandler } from "../../error-handler/error-handler"; import { ErrorHandler } from "../../error-handler/error-handler";
import { ReplicationJob, ReplicationTasks, Comparator, ReplicationJobItem, State } from "../../service/interface"; import { ReplicationJob, ReplicationTasks, Comparator, ReplicationJobItem, State } from "../../service/interface";
import { CustomComparator, DEFAULT_PAGE_SIZE, calculatePage, doFiltering, doSorting } from "../../utils"; import { CustomComparator, DEFAULT_PAGE_SIZE, calculatePage, doFiltering, doSorting } from "../../utils";
import { RequestQueryParams } from "../../service/RequestQueryParams"; import { RequestQueryParams } from "../../service/RequestQueryParams";
const taskStatus = 'InProgress';
@Component({ @Component({
selector: 'replication-tasks', selector: 'replication-tasks',
templateUrl: './replication-tasks.component.html', templateUrl: './replication-tasks.component.html',
styleUrls: ['./replication-tasks.component.scss'] styleUrls: ['./replication-tasks.component.scss']
}) })
export class ReplicationTasksComponent implements OnInit { export class ReplicationTasksComponent implements OnInit, OnDestroy {
isOpenFilterTag: boolean; isOpenFilterTag: boolean;
selectedRow: []; selectedRow: [];
currentPage: number = 1; currentPage: number = 1;
@ -28,6 +30,7 @@ export class ReplicationTasksComponent implements OnInit {
tasksCopy: ReplicationTasks[] = []; tasksCopy: ReplicationTasks[] = [];
stopOnGoing: boolean; stopOnGoing: boolean;
executions: ReplicationJobItem[]; executions: ReplicationJobItem[];
timerDelay: Subscription;
@Input() executionId: string; @Input() executionId: string;
startTimeComparator: Comparator<ReplicationJob> = new CustomComparator< startTimeComparator: Comparator<ReplicationJob> = new CustomComparator<
ReplicationJob ReplicationJob
@ -84,6 +87,10 @@ export class ReplicationTasksComponent implements OnInit {
return this.executions && this.executions['in_progress']; return this.executions && this.executions['in_progress'];
} }
public get stoppedNum(): string {
return this.executions && this.executions['stopped'];
}
stopJob() { stopJob() {
this.stopOnGoing = true; this.stopOnGoing = true;
this.replicationService.stopJobs(this.executionId) this.replicationService.stopJobs(this.executionId)
@ -103,8 +110,13 @@ export class ReplicationTasksComponent implements OnInit {
return this.replicationService.getJobBaseUrl() + "/executions/" + this.executionId + "/tasks/" + taskId + "/log"; return this.replicationService.getJobBaseUrl() + "/executions/" + this.executionId + "/tasks/" + taskId + "/log";
} }
clrLoadTasks(state: State): void { ngOnDestroy() {
if (this.timerDelay) {
this.timerDelay.unsubscribe();
}
}
clrLoadTasks(state: State): void {
if (!state || !state.page) { if (!state || !state.page) {
return; return;
} }
@ -128,6 +140,24 @@ export class ReplicationTasksComponent implements OnInit {
this.totalCount = res.length; this.totalCount = res.length;
this.tasks = res; // Keep the data this.tasks = res; // Keep the data
this.taskItem = this.tasks.filter(tasks => tasks.resource_type !== ""); this.taskItem = this.tasks.filter(tasks => tasks.resource_type !== "");
if (!this.timerDelay) {
this.timerDelay = timer(10000, 10000).subscribe(() => {
let count: number = 0;
this.tasks.forEach(tasks => {
if (
tasks.status === taskStatus
) {
count++;
}
});
if (count > 0) {
this.clrLoadTasks(this.currentState);
} else {
this.timerDelay.unsubscribe();
this.timerDelay = null;
}
});
}
this.taskItem = doFiltering<ReplicationTasks>(this.taskItem, state); this.taskItem = doFiltering<ReplicationTasks>(this.taskItem, state);
this.taskItem = doSorting<ReplicationTasks>(this.taskItem, state); this.taskItem = doSorting<ReplicationTasks>(this.taskItem, state);

View File

@ -55,6 +55,7 @@
<clr-dg-column [clrDgSortBy]="creationTimeComparator">{{'REPLICATION.CREATION_TIME' | translate}}</clr-dg-column> <clr-dg-column [clrDgSortBy]="creationTimeComparator">{{'REPLICATION.CREATION_TIME' | translate}}</clr-dg-column>
<clr-dg-column>{{'REPLICATION.DURATION' | translate}}</clr-dg-column> <clr-dg-column>{{'REPLICATION.DURATION' | translate}}</clr-dg-column>
<clr-dg-column>{{'REPLICATION.SUCCESS_RATE' | translate}}</clr-dg-column> <clr-dg-column>{{'REPLICATION.SUCCESS_RATE' | translate}}</clr-dg-column>
<clr-dg-column>{{'REPLICATION.TOTAL' | translate}}</clr-dg-column>
<clr-dg-column [clrDgField]="'status'">{{'REPLICATION.STATUS' | translate}}</clr-dg-column> <clr-dg-column [clrDgField]="'status'">{{'REPLICATION.STATUS' | translate}}</clr-dg-column>
<clr-dg-placeholder>{{'REPLICATION.JOB_PLACEHOLDER' | translate }}</clr-dg-placeholder> <clr-dg-placeholder>{{'REPLICATION.JOB_PLACEHOLDER' | translate }}</clr-dg-placeholder>
<clr-dg-row *ngFor="let j of jobs" [clrDgItem]="j"> <clr-dg-row *ngFor="let j of jobs" [clrDgItem]="j">
@ -67,6 +68,7 @@
<clr-dg-cell> <clr-dg-cell>
{{(j.succeed > 0 ? j.succeed / j.total : 0) | percent }} {{(j.succeed > 0 ? j.succeed / j.total : 0) | percent }}
</clr-dg-cell> </clr-dg-cell>
<clr-dg-cell>{{j.total}}</clr-dg-cell>
<clr-dg-cell> <clr-dg-cell>
{{j.status}} {{j.status}}
<clr-tooltip> <clr-tooltip>

View File

@ -39,7 +39,8 @@ describe('Replication Component (inline template)', () => {
"deletion": false, "deletion": false,
"src_registry": {id: 3}, "src_registry": {id: 3},
"src_namespaces": ["name1"], "src_namespaces": ["name1"],
"enabled": true "enabled": true,
"override": true
}, },
{ {
"id": 2, "id": 2,
@ -51,7 +52,8 @@ describe('Replication Component (inline template)', () => {
"deletion": false, "deletion": false,
"dest_registry": {id: 5}, "dest_registry": {id: 5},
"src_namespaces": ["name1"], "src_namespaces": ["name1"],
"enabled": true "enabled": true,
"override": true
} }
]; ];

View File

@ -114,6 +114,7 @@ export interface ReplicationRule extends Base {
src_namespaces: string []; src_namespaces: string [];
dest_namespace?: string; dest_namespace?: string;
enabled: boolean; enabled: boolean;
override: boolean;
} }
export class Filter { export class Filter {

View File

@ -23,6 +23,11 @@ export const errorHandler = function (error: any): string {
if (!error) { if (!error) {
return "UNKNOWN_ERROR"; return "UNKNOWN_ERROR";
} }
if (error && error._body) {
return error._body;
}
if (!(error.statusCode || error.status)) { if (!(error.statusCode || error.status)) {
// treat as string message // treat as string message
return '' + error; return '' + error;

View File

@ -340,6 +340,8 @@
"OF": "of" "OF": "of"
}, },
"REPLICATION": { "REPLICATION": {
"TOTAL": "Total",
"OVERRIDE": "Override",
"OPERATION": "Operation", "OPERATION": "Operation",
"CURRENT": "current", "CURRENT": "current",
"FILTER_PLACEHOLDER": "Filter Tasks", "FILTER_PLACEHOLDER": "Filter Tasks",
@ -386,7 +388,7 @@
"ENABLE": "Enable", "ENABLE": "Enable",
"DISABLE": "Disable", "DISABLE": "Disable",
"REPLICATION_MODE": "Replication Mode", "REPLICATION_MODE": "Replication Mode",
"SRC_NAMESPACE": "Source registry:Namespace", "SRC_REGISTRY": "Source registry",
"DESTINATION_NAMESPACE": "Destination registry:Namespace", "DESTINATION_NAMESPACE": "Destination registry:Namespace",
"LAST_REPLICATION":"Last Replication", "LAST_REPLICATION":"Last Replication",
"DESTINATION_NAME_IS_REQUIRED": "Endpoint name is required.", "DESTINATION_NAME_IS_REQUIRED": "Endpoint name is required.",
@ -408,7 +410,7 @@
"RUNNING": "Running", "RUNNING": "Running",
"ERROR": "Error", "ERROR": "Error",
"RETRYING": "Retrying", "RETRYING": "Retrying",
"STOPPED": "Stopped", "STOPPED": "STOPPED",
"FINISHED": "Finished", "FINISHED": "Finished",
"CANCELED": "Canceled", "CANCELED": "Canceled",
"SIMPLE": "Simple", "SIMPLE": "Simple",

View File

@ -339,6 +339,8 @@
"OF": "of" "OF": "of"
}, },
"REPLICATION": { "REPLICATION": {
"TOTAL": "Total",
"OVERRIDE": "Anular",
"CURRENT": "current", "CURRENT": "current",
"FILTER_PLACEHOLDER": "Filter Tasks", "FILTER_PLACEHOLDER": "Filter Tasks",
"STOP_TITLE": "Confirme Stop Executions", "STOP_TITLE": "Confirme Stop Executions",
@ -386,7 +388,7 @@
"ENABLE": "Activar", "ENABLE": "Activar",
"DISABLE": "Desactivar", "DISABLE": "Desactivar",
"REPLICATION_MODE": "Replication Mode", "REPLICATION_MODE": "Replication Mode",
"SRC_NAMESPACE": "Source registry:Namespace", "SRC_REGISTRY": "Source registry",
"DESTINATION_NAMESPACE": "Destination registry:Namespace", "DESTINATION_NAMESPACE": "Destination registry:Namespace",
"LAST_REPLICATION":"Last Replication", "LAST_REPLICATION":"Last Replication",
"DESTINATION_NAME_IS_REQUIRED": "El nombre del endpoint es obligatorio.", "DESTINATION_NAME_IS_REQUIRED": "El nombre del endpoint es obligatorio.",

View File

@ -324,6 +324,8 @@
"OF": "de" "OF": "de"
}, },
"REPLICATION": { "REPLICATION": {
"TOTAL": "Total",
"OVERRIDE": "Passer outre",
"CURRENT": "current", "CURRENT": "current",
"FILTER_PLACEHOLDER": "Filter Tasks", "FILTER_PLACEHOLDER": "Filter Tasks",
"STOP_TITLE": "Confirmer arrêter les exécutions", "STOP_TITLE": "Confirmer arrêter les exécutions",
@ -368,7 +370,7 @@
"ENABLE": "Activer", "ENABLE": "Activer",
"DISABLE": "Désactiver", "DISABLE": "Désactiver",
"REPLICATION_MODE": "Replication Mode", "REPLICATION_MODE": "Replication Mode",
"SRC_NAMESPACE": "Source registry:Namespace", "SRC_REGISTRY": "Source registry",
"DESTINATION_NAMESPACE": "Destination registry:Namespace", "DESTINATION_NAMESPACE": "Destination registry:Namespace",
"LAST_REPLICATION":"Last Replication", "LAST_REPLICATION":"Last Replication",
"DESTINATION_NAME_IS_REQUIRED": "Le nom du Point Final est obligatoire.", "DESTINATION_NAME_IS_REQUIRED": "Le nom du Point Final est obligatoire.",
@ -390,7 +392,7 @@
"RUNNING": "En fonctionnement", "RUNNING": "En fonctionnement",
"ERROR": "Erreur", "ERROR": "Erreur",
"RETRYING": "En train de réessayer", "RETRYING": "En train de réessayer",
"STOPPED": "Stoppé", "STOPPED": "STOPPED",
"FINISHED": "Terminé", "FINISHED": "Terminé",
"CANCELED": "Annulé", "CANCELED": "Annulé",
"SIMPLE": "Simple", "SIMPLE": "Simple",

View File

@ -338,6 +338,8 @@
"OF": "de" "OF": "de"
}, },
"REPLICATION": { "REPLICATION": {
"TOTAL": "Total",
"OVERRIDE": "Substituir",
"CURRENT": "current", "CURRENT": "current",
"FILTER_PLACEHOLDER": "Filter Tasks", "FILTER_PLACEHOLDER": "Filter Tasks",
"STOP_TITLE": "Confirme as execuções de parada", "STOP_TITLE": "Confirme as execuções de parada",
@ -385,7 +387,7 @@
"ENABLE": "Habilitar", "ENABLE": "Habilitar",
"DISABLE": "Desabilitar", "DISABLE": "Desabilitar",
"REPLICATION_MODE": "Replication Mode", "REPLICATION_MODE": "Replication Mode",
"SRC_NAMESPACE": "Source registry:Namespace", "SRC_REGISTRY": "Source registry",
"DESTINATION_NAMESPACE": "Destination registry:Namespace", "DESTINATION_NAMESPACE": "Destination registry:Namespace",
"LAST_REPLICATION":"Last Replication", "LAST_REPLICATION":"Last Replication",
"DESTINATION_NAME_IS_REQUIRED": "Nome do Endpoint é obrigatório.", "DESTINATION_NAME_IS_REQUIRED": "Nome do Endpoint é obrigatório.",
@ -408,7 +410,7 @@
"RUNNING": "Executando", "RUNNING": "Executando",
"ERROR": "Erro", "ERROR": "Erro",
"RETRYING": "Tentando novamente", "RETRYING": "Tentando novamente",
"STOPPED": "Parada", "STOPPED": "STOPPED",
"FINISHED": "Finalizada", "FINISHED": "Finalizada",
"CANCELED": "Cancelada", "CANCELED": "Cancelada",
"SIMPLE": "Simples", "SIMPLE": "Simples",

View File

@ -339,6 +339,8 @@
"OF": "共计" "OF": "共计"
}, },
"REPLICATION": { "REPLICATION": {
"TOTAL": "总数",
"OVERRIDE": "覆盖",
"CURRENT": "当前仓库", "CURRENT": "当前仓库",
"FILTER_PLACEHOLDER": "过滤任务", "FILTER_PLACEHOLDER": "过滤任务",
"STOP_TITLE": "确认停止任务", "STOP_TITLE": "确认停止任务",
@ -386,7 +388,7 @@
"ENABLE": "启用", "ENABLE": "启用",
"DISABLE": "停用", "DISABLE": "停用",
"REPLICATION_MODE": "复制模式", "REPLICATION_MODE": "复制模式",
"SRC_NAMESPACE": "源仓库:命名空间", "SRC_REGISTRY": "源仓库",
"DESTINATION_NAMESPACE": "目标仓库:命名空间", "DESTINATION_NAMESPACE": "目标仓库:命名空间",
"LAST_REPLICATION":"最后一次复制", "LAST_REPLICATION":"最后一次复制",
"DESTINATION_NAME_IS_REQUIRED": "目标名称为必填项。", "DESTINATION_NAME_IS_REQUIRED": "目标名称为必填项。",