diff --git a/src/portal/lib/src/create-edit-endpoint/create-edit-endpoint.component.ts b/src/portal/lib/src/create-edit-endpoint/create-edit-endpoint.component.ts
index b02926711..50f681780 100644
--- a/src/portal/lib/src/create-edit-endpoint/create-edit-endpoint.component.ts
+++ b/src/portal/lib/src/create-edit-endpoint/create-edit-endpoint.component.ts
@@ -257,10 +257,7 @@ export class CreateEditEndpointComponent
},
error => {
this.onGoing = false;
- let errorMessageKey = this.handleErrorMessageKey(error.status);
- this.translateService.get(errorMessageKey).subscribe(res => {
- this.inlineAlert.showInlineError(res);
- });
+ this.inlineAlert.showInlineError(error);
this.forceRefreshView(2000);
}
);
@@ -302,27 +299,13 @@ export class CreateEditEndpointComponent
this.forceRefreshView(2000);
},
error => {
- let errorMessageKey = this.handleErrorMessageKey(error.status);
- this.translateService.get(errorMessageKey).subscribe(res => {
- this.inlineAlert.showInlineError(res);
- });
+ this.inlineAlert.showInlineError(error);
this.onGoing = false;
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() {
let changes: { [key: string]: any } = this.getChanges();
if (!isEmptyObject(changes)) {
diff --git a/src/portal/lib/src/create-edit-rule/create-edit-rule.component.html b/src/portal/lib/src/create-edit-rule/create-edit-rule.component.html
index 781114c1d..119917e10 100644
--- a/src/portal/lib/src/create-edit-rule/create-edit-rule.component.html
+++ b/src/portal/lib/src/create-edit-rule/create-edit-rule.component.html
@@ -133,12 +133,18 @@
-
diff --git a/src/portal/lib/src/create-edit-rule/create-edit-rule.component.spec.ts b/src/portal/lib/src/create-edit-rule/create-edit-rule.component.spec.ts
index 80ba905d4..e95a10331 100644
--- a/src/portal/lib/src/create-edit-rule/create-edit-rule.component.spec.ts
+++ b/src/portal/lib/src/create-edit-rule/create-edit-rule.component.spec.ts
@@ -54,7 +54,8 @@ describe("CreateEditRuleComponent (inline template)", () => {
},
filters: [],
deletion: false,
- enabled: true
+ enabled: true,
+ override: true
}
];
let mockJobs: ReplicationJobItem[] = [
@@ -166,7 +167,8 @@ describe("CreateEditRuleComponent (inline template)", () => {
},
filters: [],
deletion: false,
- enabled: true
+ enabled: true,
+ override: true
};
let mockRegistryInfo = {
diff --git a/src/portal/lib/src/create-edit-rule/create-edit-rule.component.ts b/src/portal/lib/src/create-edit-rule/create-edit-rule.component.ts
index 3c4fb61c6..303806a53 100644
--- a/src/portal/lib/src/create-edit-rule/create-edit-rule.component.ts
+++ b/src/portal/lib/src/create-edit-rule/create-edit-rule.component.ts
@@ -191,7 +191,8 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
}),
filters: this.fb.array([]),
deletion: false,
- enabled: true
+ enabled: true,
+ override: true
});
}
@@ -218,7 +219,8 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
}
},
deletion: false,
- enabled: true
+ enabled: true,
+ override: true
});
this.isPushMode = true;
}
@@ -236,6 +238,7 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
} else {
this.isPushMode = true;
}
+
setTimeout(() => {
this.ruleForm.reset({
name: rule.name,
@@ -246,7 +249,8 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
dest_registry: rule.dest_registry,
trigger: rule.trigger,
deletion: rule.deletion,
- enabled: rule.enabled
+ enabled: rule.enabled,
+ override: rule.override
});
// reset the filter list.
let filters = [];
@@ -260,7 +264,6 @@ export class CreateEditRuleComponent implements OnInit, OnDestroy {
}
});
}
-
if (!findTag) {
filters.push({ type: this.supportedFilters[i].type, value: "" });
}
diff --git a/src/portal/lib/src/endpoint/endpoint.component.ts b/src/portal/lib/src/endpoint/endpoint.component.ts
index 8e383e7ac..f1630559c 100644
--- a/src/portal/lib/src/endpoint/endpoint.component.ts
+++ b/src/portal/lib/src/endpoint/endpoint.component.ts
@@ -118,7 +118,6 @@ export class EndpointComponent implements OnInit, OnDestroy {
this.endpointService.getEndpoints(this.targetName)
.subscribe(targets => {
this.targets = targets || [];
- this.forceRefreshView(1000);
this.loading = false;
}, error => {
this.errorHandler.error(error);
diff --git a/src/portal/lib/src/list-replication-rule/list-replication-rule.component.html b/src/portal/lib/src/list-replication-rule/list-replication-rule.component.html
index 9aa54ed0e..a48a9017b 100644
--- a/src/portal/lib/src/list-replication-rule/list-replication-rule.component.html
+++ b/src/portal/lib/src/list-replication-rule/list-replication-rule.component.html
@@ -8,10 +8,10 @@
{{'REPLICATION.NAME' | translate}}
{{'REPLICATION.STATUS' | translate}}
- {{'REPLICATION.SRC_NAMESPACE' | translate}}
- {{'REPLICATION.REPLICATION_MODE' | translate}}
+ {{'REPLICATION.SRC_REGISTRY' | translate}}
{{'REPLICATION.DESTINATION_NAMESPACE' | translate}}
{{'REPLICATION.REPLICATION_TRIGGER' | translate}}
+ {{'REPLICATION.OVERRIDE' | translate}}
{{'REPLICATION.DESCRIPTION' | translate}}
{{'REPLICATION.PLACEHOLDER' | translate }}
@@ -28,7 +28,7 @@
- {{p.src_registry ? p.src_registry.name : ''}} : {{p.src_namespaces?.length>0 ? p.src_namespaces[0]: ''}}
+ {{p.src_registry ? p.src_registry.name : ''}}
1" clrTooltipTrigger shape="ellipsis-horizontal" size="18">
@@ -36,13 +36,14 @@
-
- {{p.src_registry && p.src_registry.id > 0 ? 'pull-based' : 'push-based'}}
-
{{p.dest_registry ? p.dest_registry.name : ''}} : {{p.dest_namespace? p.dest_namespace: '-'}}
{{p.trigger ? p.trigger.type : ''}}
+
+
+
+
{{p.description ? trancatedDescription(p.description) : '-'}}
diff --git a/src/portal/lib/src/list-replication-rule/list-replication-rule.component.scss b/src/portal/lib/src/list-replication-rule/list-replication-rule.component.scss
index 3ca201456..a37a9016d 100644
--- a/src/portal/lib/src/list-replication-rule/list-replication-rule.component.scss
+++ b/src/portal/lib/src/list-replication-rule/list-replication-rule.component.scss
@@ -11,3 +11,7 @@
.status-width {
width: 105px;
}
+
+.icon-style {
+ color: #C92100;
+}
diff --git a/src/portal/lib/src/list-replication-rule/list-replication-rule.component.spec.ts b/src/portal/lib/src/list-replication-rule/list-replication-rule.component.spec.ts
index 2e82de417..d8d627fef 100644
--- a/src/portal/lib/src/list-replication-rule/list-replication-rule.component.spec.ts
+++ b/src/portal/lib/src/list-replication-rule/list-replication-rule.component.spec.ts
@@ -29,7 +29,8 @@ describe('ListReplicationRuleComponent (inline template)', () => {
"deletion": false,
"src_namespaces": ["name1", "name2"],
"src_registry": {id: 3},
- "enabled": true
+ "enabled": true,
+ "override": true
},
{
"id": 2,
@@ -41,7 +42,8 @@ describe('ListReplicationRuleComponent (inline template)', () => {
"deletion": false,
"src_namespaces": ["name1", "name2"],
"dest_registry": {id: 3},
- "enabled": true
+ "enabled": true,
+ "override": true
},
];
diff --git a/src/portal/lib/src/replication/replication-tasks/replication-tasks.component.html b/src/portal/lib/src/replication/replication-tasks/replication-tasks.component.html
index bb8c6b511..f5b5db321 100644
--- a/src/portal/lib/src/replication/replication-tasks/replication-tasks.component.html
+++ b/src/portal/lib/src/replication/replication-tasks/replication-tasks.component.html
@@ -49,17 +49,25 @@
- {{'REPLICATION.SUCCESS'| translate}}
+
+
{{successNum}}
- {{'REPLICATION.FAILURE'| translate}}
+
+
{{failedNum}}
- {{'REPLICATION.IN_PROGRESS'| translate}}
+
+
{{progressNum}}
+
+
+
+ {{stoppedNum}}
+
diff --git a/src/portal/lib/src/replication/replication-tasks/replication-tasks.component.scss b/src/portal/lib/src/replication/replication-tasks/replication-tasks.component.scss
index abfa879a4..cb5f3cf31 100644
--- a/src/portal/lib/src/replication/replication-tasks/replication-tasks.component.scss
+++ b/src/portal/lib/src/replication/replication-tasks/replication-tasks.component.scss
@@ -41,9 +41,27 @@
text-align: left;
.detail-row {
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 {
flex:0 0 100px;
- margin-top: 10px;
+ margin: 10px 0 0 10px;
}
.execution-details {
width: 200px;
diff --git a/src/portal/lib/src/replication/replication-tasks/replication-tasks.component.ts b/src/portal/lib/src/replication/replication-tasks/replication-tasks.component.ts
index d74eb1223..2af8e40a5 100644
--- a/src/portal/lib/src/replication/replication-tasks/replication-tasks.component.ts
+++ b/src/portal/lib/src/replication/replication-tasks/replication-tasks.component.ts
@@ -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 { ReplicationService } from "../../service/replication.service";
import { TranslateService } from '@ngx-translate/core';
import { finalize } from "rxjs/operators";
+import { Subscription, timer } from "rxjs";
import { ErrorHandler } from "../../error-handler/error-handler";
import { ReplicationJob, ReplicationTasks, Comparator, ReplicationJobItem, State } from "../../service/interface";
import { CustomComparator, DEFAULT_PAGE_SIZE, calculatePage, doFiltering, doSorting } from "../../utils";
import { RequestQueryParams } from "../../service/RequestQueryParams";
+const taskStatus = 'InProgress';
@Component({
selector: 'replication-tasks',
templateUrl: './replication-tasks.component.html',
styleUrls: ['./replication-tasks.component.scss']
})
-export class ReplicationTasksComponent implements OnInit {
+export class ReplicationTasksComponent implements OnInit, OnDestroy {
isOpenFilterTag: boolean;
selectedRow: [];
currentPage: number = 1;
@@ -28,6 +30,7 @@ export class ReplicationTasksComponent implements OnInit {
tasksCopy: ReplicationTasks[] = [];
stopOnGoing: boolean;
executions: ReplicationJobItem[];
+ timerDelay: Subscription;
@Input() executionId: string;
startTimeComparator: Comparator = new CustomComparator<
ReplicationJob
@@ -84,6 +87,10 @@ export class ReplicationTasksComponent implements OnInit {
return this.executions && this.executions['in_progress'];
}
+ public get stoppedNum(): string {
+ return this.executions && this.executions['stopped'];
+ }
+
stopJob() {
this.stopOnGoing = true;
this.replicationService.stopJobs(this.executionId)
@@ -103,8 +110,13 @@ export class ReplicationTasksComponent implements OnInit {
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) {
return;
}
@@ -128,6 +140,24 @@ export class ReplicationTasksComponent implements OnInit {
this.totalCount = res.length;
this.tasks = res; // Keep the data
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(this.taskItem, state);
this.taskItem = doSorting(this.taskItem, state);
diff --git a/src/portal/lib/src/replication/replication.component.html b/src/portal/lib/src/replication/replication.component.html
index ec7601c68..9cf1f2e6c 100644
--- a/src/portal/lib/src/replication/replication.component.html
+++ b/src/portal/lib/src/replication/replication.component.html
@@ -55,6 +55,7 @@
{{'REPLICATION.CREATION_TIME' | translate}}
{{'REPLICATION.DURATION' | translate}}
{{'REPLICATION.SUCCESS_RATE' | translate}}
+ {{'REPLICATION.TOTAL' | translate}}
{{'REPLICATION.STATUS' | translate}}
{{'REPLICATION.JOB_PLACEHOLDER' | translate }}
@@ -67,6 +68,7 @@
{{(j.succeed > 0 ? j.succeed / j.total : 0) | percent }}
+ {{j.total}}
{{j.status}}
diff --git a/src/portal/lib/src/replication/replication.component.spec.ts b/src/portal/lib/src/replication/replication.component.spec.ts
index fde985608..1c162cd91 100644
--- a/src/portal/lib/src/replication/replication.component.spec.ts
+++ b/src/portal/lib/src/replication/replication.component.spec.ts
@@ -39,7 +39,8 @@ describe('Replication Component (inline template)', () => {
"deletion": false,
"src_registry": {id: 3},
"src_namespaces": ["name1"],
- "enabled": true
+ "enabled": true,
+ "override": true
},
{
"id": 2,
@@ -51,7 +52,8 @@ describe('Replication Component (inline template)', () => {
"deletion": false,
"dest_registry": {id: 5},
"src_namespaces": ["name1"],
- "enabled": true
+ "enabled": true,
+ "override": true
}
];
diff --git a/src/portal/lib/src/service/interface.ts b/src/portal/lib/src/service/interface.ts
index a3d1f0c70..8d1573812 100644
--- a/src/portal/lib/src/service/interface.ts
+++ b/src/portal/lib/src/service/interface.ts
@@ -114,6 +114,7 @@ export interface ReplicationRule extends Base {
src_namespaces: string [];
dest_namespace?: string;
enabled: boolean;
+ override: boolean;
}
export class Filter {
diff --git a/src/portal/lib/src/shared/shared.utils.ts b/src/portal/lib/src/shared/shared.utils.ts
index b3721558f..3c9efed7b 100644
--- a/src/portal/lib/src/shared/shared.utils.ts
+++ b/src/portal/lib/src/shared/shared.utils.ts
@@ -23,6 +23,11 @@ export const errorHandler = function (error: any): string {
if (!error) {
return "UNKNOWN_ERROR";
}
+
+ if (error && error._body) {
+ return error._body;
+ }
+
if (!(error.statusCode || error.status)) {
// treat as string message
return '' + error;
diff --git a/src/portal/src/i18n/lang/en-us-lang.json b/src/portal/src/i18n/lang/en-us-lang.json
index 78b221192..8d6832615 100644
--- a/src/portal/src/i18n/lang/en-us-lang.json
+++ b/src/portal/src/i18n/lang/en-us-lang.json
@@ -340,6 +340,8 @@
"OF": "of"
},
"REPLICATION": {
+ "TOTAL": "Total",
+ "OVERRIDE": "Override",
"OPERATION": "Operation",
"CURRENT": "current",
"FILTER_PLACEHOLDER": "Filter Tasks",
@@ -386,7 +388,7 @@
"ENABLE": "Enable",
"DISABLE": "Disable",
"REPLICATION_MODE": "Replication Mode",
- "SRC_NAMESPACE": "Source registry:Namespace",
+ "SRC_REGISTRY": "Source registry",
"DESTINATION_NAMESPACE": "Destination registry:Namespace",
"LAST_REPLICATION":"Last Replication",
"DESTINATION_NAME_IS_REQUIRED": "Endpoint name is required.",
@@ -408,7 +410,7 @@
"RUNNING": "Running",
"ERROR": "Error",
"RETRYING": "Retrying",
- "STOPPED": "Stopped",
+ "STOPPED": "STOPPED",
"FINISHED": "Finished",
"CANCELED": "Canceled",
"SIMPLE": "Simple",
diff --git a/src/portal/src/i18n/lang/es-es-lang.json b/src/portal/src/i18n/lang/es-es-lang.json
index a8a09bb4d..674033f3e 100644
--- a/src/portal/src/i18n/lang/es-es-lang.json
+++ b/src/portal/src/i18n/lang/es-es-lang.json
@@ -339,6 +339,8 @@
"OF": "of"
},
"REPLICATION": {
+ "TOTAL": "Total",
+ "OVERRIDE": "Anular",
"CURRENT": "current",
"FILTER_PLACEHOLDER": "Filter Tasks",
"STOP_TITLE": "Confirme Stop Executions",
@@ -386,7 +388,7 @@
"ENABLE": "Activar",
"DISABLE": "Desactivar",
"REPLICATION_MODE": "Replication Mode",
- "SRC_NAMESPACE": "Source registry:Namespace",
+ "SRC_REGISTRY": "Source registry",
"DESTINATION_NAMESPACE": "Destination registry:Namespace",
"LAST_REPLICATION":"Last Replication",
"DESTINATION_NAME_IS_REQUIRED": "El nombre del endpoint es obligatorio.",
diff --git a/src/portal/src/i18n/lang/fr-fr-lang.json b/src/portal/src/i18n/lang/fr-fr-lang.json
index 8ea812ff7..e8da0d3e1 100644
--- a/src/portal/src/i18n/lang/fr-fr-lang.json
+++ b/src/portal/src/i18n/lang/fr-fr-lang.json
@@ -324,6 +324,8 @@
"OF": "de"
},
"REPLICATION": {
+ "TOTAL": "Total",
+ "OVERRIDE": "Passer outre",
"CURRENT": "current",
"FILTER_PLACEHOLDER": "Filter Tasks",
"STOP_TITLE": "Confirmer arrêter les exécutions",
@@ -368,7 +370,7 @@
"ENABLE": "Activer",
"DISABLE": "Désactiver",
"REPLICATION_MODE": "Replication Mode",
- "SRC_NAMESPACE": "Source registry:Namespace",
+ "SRC_REGISTRY": "Source registry",
"DESTINATION_NAMESPACE": "Destination registry:Namespace",
"LAST_REPLICATION":"Last Replication",
"DESTINATION_NAME_IS_REQUIRED": "Le nom du Point Final est obligatoire.",
@@ -390,7 +392,7 @@
"RUNNING": "En fonctionnement",
"ERROR": "Erreur",
"RETRYING": "En train de réessayer",
- "STOPPED": "Stoppé",
+ "STOPPED": "STOPPED",
"FINISHED": "Terminé",
"CANCELED": "Annulé",
"SIMPLE": "Simple",
diff --git a/src/portal/src/i18n/lang/pt-br-lang.json b/src/portal/src/i18n/lang/pt-br-lang.json
index 9537e9762..f7ff18433 100644
--- a/src/portal/src/i18n/lang/pt-br-lang.json
+++ b/src/portal/src/i18n/lang/pt-br-lang.json
@@ -338,6 +338,8 @@
"OF": "de"
},
"REPLICATION": {
+ "TOTAL": "Total",
+ "OVERRIDE": "Substituir",
"CURRENT": "current",
"FILTER_PLACEHOLDER": "Filter Tasks",
"STOP_TITLE": "Confirme as execuções de parada",
@@ -385,7 +387,7 @@
"ENABLE": "Habilitar",
"DISABLE": "Desabilitar",
"REPLICATION_MODE": "Replication Mode",
- "SRC_NAMESPACE": "Source registry:Namespace",
+ "SRC_REGISTRY": "Source registry",
"DESTINATION_NAMESPACE": "Destination registry:Namespace",
"LAST_REPLICATION":"Last Replication",
"DESTINATION_NAME_IS_REQUIRED": "Nome do Endpoint é obrigatório.",
@@ -408,7 +410,7 @@
"RUNNING": "Executando",
"ERROR": "Erro",
"RETRYING": "Tentando novamente",
- "STOPPED": "Parada",
+ "STOPPED": "STOPPED",
"FINISHED": "Finalizada",
"CANCELED": "Cancelada",
"SIMPLE": "Simples",
diff --git a/src/portal/src/i18n/lang/zh-cn-lang.json b/src/portal/src/i18n/lang/zh-cn-lang.json
index 58c7e0051..567d50516 100644
--- a/src/portal/src/i18n/lang/zh-cn-lang.json
+++ b/src/portal/src/i18n/lang/zh-cn-lang.json
@@ -339,6 +339,8 @@
"OF": "共计"
},
"REPLICATION": {
+ "TOTAL": "总数",
+ "OVERRIDE": "覆盖",
"CURRENT": "当前仓库",
"FILTER_PLACEHOLDER": "过滤任务",
"STOP_TITLE": "确认停止任务",
@@ -386,7 +388,7 @@
"ENABLE": "启用",
"DISABLE": "停用",
"REPLICATION_MODE": "复制模式",
- "SRC_NAMESPACE": "源仓库:命名空间",
+ "SRC_REGISTRY": "源仓库",
"DESTINATION_NAMESPACE": "目标仓库:命名空间",
"LAST_REPLICATION":"最后一次复制",
"DESTINATION_NAME_IS_REQUIRED": "目标名称为必填项。",