From 757a99bc6ea32518c359dbe48a015cf00c5b8892 Mon Sep 17 00:00:00 2001 From: pfh Date: Wed, 17 Jan 2018 11:28:28 +0800 Subject: [PATCH] Add add endpoint button in replication rule Modify stop job button privilege Modify dispay issue about replication rule --- .../confirmation-dialog.component.html.ts | 2 +- .../create-edit-endpoint.component.ts | 2 +- .../src/endpoint/endpoint.component.html.ts | 4 +-- src/ui_ng/lib/src/index.ts | 1 + .../inline-alert.component.css.ts | 1 - .../list-replication-rule.component.html.ts | 4 +-- .../list-replication-rule.component.ts | 1 + .../replication/replication.component.html.ts | 4 +-- .../src/replication/replication.component.ts | 16 ++++++--- src/ui_ng/package.json | 2 +- .../replication-rule.component.ts | 35 ++++++++++++++----- .../replication-rule/replication-rule.css | 7 ++-- .../replication-rule/replication-rule.html | 9 ++--- .../total-replication-page.component.html | 2 +- .../total-replication-page.component.ts | 7 ++++ .../confirmation-dialog.component.html | 2 +- src/ui_ng/src/i18n/lang/en-us-lang.json | 14 ++++---- src/ui_ng/src/i18n/lang/es-es-lang.json | 13 ++++--- src/ui_ng/src/i18n/lang/zh-cn-lang.json | 15 ++++---- 19 files changed, 93 insertions(+), 48 deletions(-) diff --git a/src/ui_ng/lib/src/confirmation-dialog/confirmation-dialog.component.html.ts b/src/ui_ng/lib/src/confirmation-dialog/confirmation-dialog.component.html.ts index 252030497..50e884c9b 100644 --- a/src/ui_ng/lib/src/confirmation-dialog/confirmation-dialog.component.html.ts +++ b/src/ui_ng/lib/src/confirmation-dialog/confirmation-dialog.component.html.ts @@ -38,7 +38,7 @@ export const CONFIRMATION_DIALOG_TEMPLATE: string = ` - + diff --git a/src/ui_ng/lib/src/create-edit-endpoint/create-edit-endpoint.component.ts b/src/ui_ng/lib/src/create-edit-endpoint/create-edit-endpoint.component.ts index 967994275..36240b8f1 100644 --- a/src/ui_ng/lib/src/create-edit-endpoint/create-edit-endpoint.component.ts +++ b/src/ui_ng/lib/src/create-edit-endpoint/create-edit-endpoint.component.ts @@ -42,7 +42,7 @@ import { Subscription } from 'rxjs/Subscription'; const FAKE_PASSWORD = 'rjGcfuRu'; @Component({ - selector: 'create-edit-endpoint', + selector: 'hbr-create-edit-endpoint', template: CREATE_EDIT_ENDPOINT_TEMPLATE, styles: [CREATE_EDIT_ENDPOINT_STYLE] }) diff --git a/src/ui_ng/lib/src/endpoint/endpoint.component.html.ts b/src/ui_ng/lib/src/endpoint/endpoint.component.html.ts index d1ad201dd..17f4d981c 100644 --- a/src/ui_ng/lib/src/endpoint/endpoint.component.html.ts +++ b/src/ui_ng/lib/src/endpoint/endpoint.component.html.ts @@ -25,7 +25,7 @@ export const ENDPOINT_TEMPLATE: string = ` {{'CONFIG.VERIFY_REMOTE_CERT' | translate }} {{'DESTINATION.CREATION_TIME' | translate}} {{'DESTINATION.PLACEHOLDER' | translate }} - + {{t.name}} {{t.endpoint}} @@ -42,6 +42,6 @@ export const ENDPOINT_TEMPLATE: string = ` - + `; \ No newline at end of file diff --git a/src/ui_ng/lib/src/index.ts b/src/ui_ng/lib/src/index.ts index 586a56c5f..79858a122 100644 --- a/src/ui_ng/lib/src/index.ts +++ b/src/ui_ng/lib/src/index.ts @@ -7,6 +7,7 @@ export * from './log/index'; export * from './filter/index'; export * from './endpoint/index'; export * from './repository/index'; +export * from './create-edit-endpoint/index'; export * from './repository-stackview/index'; export * from './tag/index'; export * from './list-replication-rule/index'; diff --git a/src/ui_ng/lib/src/inline-alert/inline-alert.component.css.ts b/src/ui_ng/lib/src/inline-alert/inline-alert.component.css.ts index 4c459b707..68fe7c857 100644 --- a/src/ui_ng/lib/src/inline-alert/inline-alert.component.css.ts +++ b/src/ui_ng/lib/src/inline-alert/inline-alert.component.css.ts @@ -8,7 +8,6 @@ export const INLINE_ALERT_STYLE: string = ` min-width: 30px !important; } .alert-item { - display: inline-block; text-align: center; } :host >>> .alert-icon-wrapper{ diff --git a/src/ui_ng/lib/src/list-replication-rule/list-replication-rule.component.html.ts b/src/ui_ng/lib/src/list-replication-rule/list-replication-rule.component.html.ts index d0ddaa645..82800307d 100644 --- a/src/ui_ng/lib/src/list-replication-rule/list-replication-rule.component.html.ts +++ b/src/ui_ng/lib/src/list-replication-rule/list-replication-rule.component.html.ts @@ -13,9 +13,9 @@ export const LIST_REPLICATION_RULE_TEMPLATE: string = ` {{'REPLICATION.PROJECT' | translate}} {{'REPLICATION.DESCRIPTION' | translate}} {{'REPLICATION.DESTINATION_NAME' | translate}} - {{'REPLICATION.SCHEDULE' | translate}} + {{'REPLICATION.MODE' | translate}} {{'REPLICATION.PLACEHOLDER' | translate }} - + {{p.name}} {{p.projects?.length>0 ? p.projects[0].name : ''}} diff --git a/src/ui_ng/lib/src/list-replication-rule/list-replication-rule.component.ts b/src/ui_ng/lib/src/list-replication-rule/list-replication-rule.component.ts index 83d595299..05526f08b 100644 --- a/src/ui_ng/lib/src/list-replication-rule/list-replication-rule.component.ts +++ b/src/ui_ng/lib/src/list-replication-rule/list-replication-rule.component.ts @@ -194,6 +194,7 @@ export class ListReplicationRuleComponent implements OnInit, OnChanges { } selectRule(rule: ReplicationRule): void { + this.selectedId = rule.id || ''; this.selectedRow = []; this.selectOne.emit(rule); this.hasJobs.emit(true); diff --git a/src/ui_ng/lib/src/replication/replication.component.html.ts b/src/ui_ng/lib/src/replication/replication.component.html.ts index 3246ae2ce..9e419cc4f 100644 --- a/src/ui_ng/lib/src/replication/replication.component.html.ts +++ b/src/ui_ng/lib/src/replication/replication.component.html.ts @@ -13,7 +13,7 @@ export const REPLICATION_TEMPLATE: string = `
-
+
{{'REPLICATION.REPLICATION_JOBS' | translate}}
@@ -40,7 +40,7 @@ export const REPLICATION_TEMPLATE: string = `
- +
{{'REPLICATION.NAME' | translate}} diff --git a/src/ui_ng/lib/src/replication/replication.component.ts b/src/ui_ng/lib/src/replication/replication.component.ts index cdfc87544..cb284eb0d 100644 --- a/src/ui_ng/lib/src/replication/replication.component.ts +++ b/src/ui_ng/lib/src/replication/replication.component.ts @@ -318,14 +318,20 @@ export class ReplicationComponent implements OnInit, OnDestroy { .subscribe(res => findedList = BathInfoChanges(findedList, res)); }) .catch(error => { - this.translateService.get('BATCH.REPLICATE_FAILURE').subscribe(res => { - findedList = BathInfoChanges(findedList, res, false, true); - }); + if (error && error.status === 412) { + Observable.forkJoin(this.translateService.get('BATCH.REPLICATE_FAILURE'), + this.translateService.get('REPLICATION.REPLICATE_SUMMARY_FAILURE')) + .subscribe(function (res) { + findedList = BathInfoChanges(findedList, res[0], false, true, res[1]); + }); + } else { + this.translateService.get('BATCH.REPLICATE_FAILURE').subscribe(res => { + findedList = BathInfoChanges(findedList, res, false, true); + }); + } }); } - - customRedirect(rule: ReplicationRule) { this.redirect.emit(rule); } diff --git a/src/ui_ng/package.json b/src/ui_ng/package.json index 36a46656a..5419f3e62 100644 --- a/src/ui_ng/package.json +++ b/src/ui_ng/package.json @@ -31,7 +31,7 @@ "clarity-icons": "^0.10.17", "clarity-ui": "^0.10.17", "core-js": "^2.4.1", - "harbor-ui": "0.6.19", + "harbor-ui": "0.6.21", "intl": "^1.2.5", "mutationobserver-shim": "^0.3.2", "ngx-cookie": "^1.0.0", diff --git a/src/ui_ng/src/app/replication/replication-rule/replication-rule.component.ts b/src/ui_ng/src/app/replication/replication-rule/replication-rule.component.ts index f7047db37..19b563f64 100644 --- a/src/ui_ng/src/app/replication/replication-rule/replication-rule.component.ts +++ b/src/ui_ng/src/app/replication/replication-rule/replication-rule.component.ts @@ -13,6 +13,7 @@ import {ConfirmationMessage} from "../../shared/confirmation-dialog/confirmation import {Subject} from "rxjs/Subject"; import {ListProjectModelComponent} from "./list-project-model/list-project-model.component"; import {toPromise, isEmptyObject, compareValue} from "harbor-ui/src/utils"; +import {CreateEditEndpointComponent} from "harbor-ui/src/create-edit-endpoint/create-edit-endpoint.component"; const ONE_HOUR_SECONDS: number = 3600; const ONE_DAY_SECONDS: number = 24 * ONE_HOUR_SECONDS; @@ -23,7 +24,7 @@ const ONE_DAY_SECONDS: number = 24 * ONE_HOUR_SECONDS; styleUrls: ['replication-rule.css'] }) -export class ReplicationRuleComponent implements OnInit, AfterViewInit, OnDestroy { +export class ReplicationRuleComponent implements OnInit, OnDestroy { _localTime: Date = new Date(); policyId: number; projectId: number; @@ -33,7 +34,7 @@ export class ReplicationRuleComponent implements OnInit, AfterViewInit, OnDestro isScheduleOpt: boolean; isImmediate: boolean = true; noProjectInfo: string; - noEndpointInfo: string; + noEndpointInfo: boolean; filterCount: number = 0; selectedprojectList: Project[] = []; triggerNames: string[] = ['Immediate', 'Scheduled', 'Manual']; @@ -56,6 +57,9 @@ export class ReplicationRuleComponent implements OnInit, AfterViewInit, OnDestro @ViewChild(ListProjectModelComponent) projectListModel: ListProjectModelComponent; + @ViewChild(CreateEditEndpointComponent) + createEditEndpointComponent: CreateEditEndpointComponent; + baseFilterData(name: string, option: string[], state: boolean) { return { name: name, @@ -78,7 +82,7 @@ export class ReplicationRuleComponent implements OnInit, AfterViewInit, OnDestro Promise.all([this.repService.getEndpoints(), this.repService.listProjects()]) .then(res => { if (!res[0]) { - this.noEndpointInfo = 'NO_ENDPOINT_INFO'; + this.noEndpointInfo = true; }else { this.targetList = res[0]; if (!this.policyId) { @@ -86,7 +90,7 @@ export class ReplicationRuleComponent implements OnInit, AfterViewInit, OnDestro } } if (!res[1]) { - this.noProjectInfo = 'NO_PROJECT_INFO'; + this.noProjectInfo = 'REPLICATION.NO_PROJECT_INFO'; }else { if (!this.policyId && !this.projectId) { this.setProject([res[1][0]]); @@ -95,7 +99,7 @@ export class ReplicationRuleComponent implements OnInit, AfterViewInit, OnDestro this.setProject( res[1].filter(rule => rule.project_id === this.projectId)); } } - if (res[0] && res[1] && !this.policyId) { + if (!this.policyId) { this.copyUpdateForm = Object.assign({}, this.ruleForm.value); } }); @@ -133,9 +137,6 @@ export class ReplicationRuleComponent implements OnInit, AfterViewInit, OnDestro }); } - ngAfterViewInit(): void { - } - ngOnDestroy(): void { if (this.confirmSub) { this.confirmSub.unsubscribe(); @@ -145,6 +146,10 @@ export class ReplicationRuleComponent implements OnInit, AfterViewInit, OnDestro } } + get isVaild() { + return !(this.isRuleNameExist || this.noProjectInfo || this.noEndpointInfo); + } + createForm() { this.ruleForm = this.fb.group({ name: ['', Validators.required], @@ -450,6 +455,20 @@ export class ReplicationRuleComponent implements OnInit, AfterViewInit, OnDestro this.inProgress = true; } + openModal() { + this.createEditEndpointComponent.openCreateEditTarget(true); + } + + reload($event: boolean) { + if ($event) { + Promise.all([this.repService.getEndpoints()]).then(res => { + this.targetList = res[0]; + this.setTarget([this.targetList[this.targetList.length - 1]]); + }); + this.noEndpointInfo = false; + } + } + onCancel(): void { this.router.navigate(['/harbor/replications']); } diff --git a/src/ui_ng/src/app/replication/replication-rule/replication-rule.css b/src/ui_ng/src/app/replication/replication-rule/replication-rule.css index 63b87a8d3..b78fda952 100644 --- a/src/ui_ng/src/app/replication/replication-rule/replication-rule.css +++ b/src/ui_ng/src/app/replication/replication-rule/replication-rule.css @@ -28,10 +28,13 @@ label:first-child { .filterSelect label{width: 160px;} .filterSelect label input{width: 100%;} .cursor{cursor: pointer;} +.pull-left{float: left;} .padLeft0{padding-left: 0;} -.floatSet {display: inline-block; float: left; width: 120px;margin-right: 10px;} +.floatSet {display: inline-block; width: 120px;margin-right: 10px;} .form-group{ min-height: 36px;} .projectInput{float: left;} .projectInput input{width: 185px;background-color: white;} -.switchIcon{width:20px;height:20px; margin-top: 2px;margin-left: 15px;} \ No newline at end of file +.switchIcon{width:20px;height:20px; margin-top: 2px;margin-left: 5px;} +.addEndpoint{ display: inline-block; line-height: 20px; margin-top: 8px; + vertical-align: bottom; padding-left:10px; cursor: pointer;} \ No newline at end of file diff --git a/src/ui_ng/src/app/replication/replication-rule/replication-rule.html b/src/ui_ng/src/app/replication/replication-rule/replication-rule.html index 2765c080c..62abc53b9 100644 --- a/src/ui_ng/src/app/replication/replication-rule/replication-rule.html +++ b/src/ui_ng/src/app/replication/replication-rule/replication-rule.html @@ -1,6 +1,6 @@
< {{'SIDE_NAV.SYSTEM_MGMT.REPLICATION' | translate}} - <{{'SIDE_NAV.PROJECTS' | translate}}   {{'SIDE_NAV.SYSTEM_MGMT.REPLICATION' | translate}} + <{{'SIDE_NAV.PROJECTS' | translate}}   {{'SIDE_NAV.SYSTEM_MGMT.REPLICATION' | translate | lowercase}}

{{headerTitle | translate}}

@@ -57,12 +57,12 @@
-
+
- + {{'REPLICATION.NEW' | translate}}
@@ -116,9 +116,10 @@
- +
+
\ No newline at end of file diff --git a/src/ui_ng/src/app/replication/total-replication/total-replication-page.component.html b/src/ui_ng/src/app/replication/total-replication/total-replication-page.component.html index 18dcdc455..c4ef6f6e5 100644 --- a/src/ui_ng/src/app/replication/total-replication/total-replication-page.component.html +++ b/src/ui_ng/src/app/replication/total-replication/total-replication-page.component.html @@ -1,4 +1,4 @@

{{'SIDE_NAV.SYSTEM_MGMT.REPLICATION' | translate}}

- +
\ No newline at end of file diff --git a/src/ui_ng/src/app/replication/total-replication/total-replication-page.component.ts b/src/ui_ng/src/app/replication/total-replication/total-replication-page.component.ts index 6f89caa2a..c9e951046 100644 --- a/src/ui_ng/src/app/replication/total-replication/total-replication-page.component.ts +++ b/src/ui_ng/src/app/replication/total-replication/total-replication-page.component.ts @@ -15,6 +15,7 @@ import { Component } from '@angular/core'; import {Router,ActivatedRoute} from "@angular/router"; import {ReplicationRule} from "../replication-rule/replication-rule"; +import {SessionService} from "../../shared/session.service"; @Component({ selector: 'total-replication', @@ -23,6 +24,7 @@ import {ReplicationRule} from "../replication-rule/replication-rule"; export class TotalReplicationPageComponent { constructor(private router: Router, + private session: SessionService, private activeRoute: ActivatedRoute){} customRedirect(rule: ReplicationRule): void { if (rule) { @@ -30,6 +32,11 @@ export class TotalReplicationPageComponent { } } + public get isSystemAdmin(): boolean { + let account = this.session.getCurrentUser(); + return account != null && account.has_admin_role > 0; + } + openEditPage(id: number): void { this.router.navigate([id, 'rule'], { relativeTo: this.activeRoute }); } diff --git a/src/ui_ng/src/app/shared/confirmation-dialog/confirmation-dialog.component.html b/src/ui_ng/src/app/shared/confirmation-dialog/confirmation-dialog.component.html index 503019c5f..cd01de777 100644 --- a/src/ui_ng/src/app/shared/confirmation-dialog/confirmation-dialog.component.html +++ b/src/ui_ng/src/app/shared/confirmation-dialog/confirmation-dialog.component.html @@ -37,7 +37,7 @@ - +
diff --git a/src/ui_ng/src/i18n/lang/en-us-lang.json b/src/ui_ng/src/i18n/lang/en-us-lang.json index ce5088545..545191184 100644 --- a/src/ui_ng/src/i18n/lang/en-us-lang.json +++ b/src/ui_ng/src/i18n/lang/en-us-lang.json @@ -42,8 +42,8 @@ "DELETED_FAILURE": "Deleted failed", "SWITCH_SUCCESS": "Switch successfully", "SWITCH_FAILURE": "Switch failed", - "REPLICATE_SUCCESS": "Replicate successfully", - "REPLICATE_FAILURE": "Replicate failed" + "REPLICATE_SUCCESS": "Started successfully", + "REPLICATE_FAILURE": "Started failed" }, "TOOLTIP": { "EMAIL": "Email should be a valid email address like name@example.com.", @@ -250,7 +250,8 @@ "REPLICATION_TITLE": "Confirm Rules replication", "REPLICATION_SUMMARY": "Do you want to replicate the Rules {{param}}?", "DELETION_TITLE_FAILURE": "failed to delete Rule Deletion", - "DELETION_SUMMARY_FAILURE": "{{param}} have pending/running/retrying status", + "DELETION_SUMMARY_FAILURE": "have pending/running/retrying status", + "REPLICATE_SUMMARY_FAILURE": "have pending/running status", "FILTER_TARGETS_PLACEHOLDER": "Filter Endpoints", "DELETION_TITLE_TARGET": "Confirm Endpoint Deletion", "DELETION_SUMMARY_TARGET": "Do you want to delete the endpoint {{param}}?", @@ -311,14 +312,14 @@ "TOGGLED_SUCCESS": "Toggled replication rule status successfully.", "CANNOT_EDIT": "Replication rule cannot be changed while it is enabled.", "POLICY_ALREADY_EXISTS": "Replication rule already exists.", - "FAILED_TO_DELETE_POLICY_ENABLED": "Cannot delete rule: rule has unfinished job(s) or rule is enabled.", + "FAILED_TO_DELETE_POLICY_ENABLED": "Cannot delete rule: rule has unfinished job(s)", "FOUND_ERROR_IN_JOBS": "Found errors in the replication job(s), please check.", "INVALID_DATE": "Invalid date.", "PLACEHOLDER": "We couldn't find any replication rules!", "JOB_PLACEHOLDER": "We couldn't find any replication jobs!", "JOB_LOG_VIEWER": "View Replication Job Log", "NO_ENDPOINT_INFO": "Please go to registries and add an endpoint first", - "NO_PROJECT_INFO": "Please go to projects and add a project first", + "NO_PROJECT_INFO": "Please go to projects and add a project name first", "FILTER": "Filter", "SCHEDULE": "Scheduled", "MANUAL": "Manual", @@ -330,7 +331,8 @@ "SOURCE": "Source", "REPLICATE": "Replicate", "DELETE_REMOTE_IMAGES":"Delete remote images when locally deleted", - "REPLICATE_IMMEDIATE":"Replicate existing images immediately" + "REPLICATE_IMMEDIATE":"Replicate existing images immediately", + "NEW": "New" }, "DESTINATION": { "NEW_ENDPOINT": "New Endpoint", diff --git a/src/ui_ng/src/i18n/lang/es-es-lang.json b/src/ui_ng/src/i18n/lang/es-es-lang.json index 04143639f..9e66ad64e 100644 --- a/src/ui_ng/src/i18n/lang/es-es-lang.json +++ b/src/ui_ng/src/i18n/lang/es-es-lang.json @@ -42,8 +42,8 @@ "DELETED_FAILURE": "Deleted failed", "SWITCH_SUCCESS": "Switch successfully", "SWITCH_FAILURE": "Switch failed", - "REPLICATE_SUCCESS": "Replicate successfully", - "REPLICATE_FAILURE": "Replicate failed" + "REPLICATE_SUCCESS": "Started successfully", + "REPLICATE_FAILURE": "Started failed" }, "TOOLTIP": { "EMAIL": "El email debe ser una dirección válida como nombre@ejemplo.com.", @@ -247,7 +247,8 @@ "DELETION_TITLE": "Confirmar Eliminación de Regla", "DELETION_SUMMARY": "¿Quiere eliminar la regla {{param}}?", "DELETION_TITLE_FAILURE": "failed to delete Rule Deletion", - "DELETION_SUMMARY_FAILURE": "{{param}} have pending/running/retrying status", + "DELETION_SUMMARY_FAILURE": "have pending/running/retrying status", + "REPLICATE_SUMMARY_FAILURE": "have pending/running status", "REPLICATION_TITLE": "Confirm Rules replication", "REPLICATION_SUMMARY": "Do you want to replicate the Rules {{param}}?", "FILTER_TARGETS_PLACEHOLDER": "Filtrar Endpoints", @@ -317,7 +318,7 @@ "JOB_PLACEHOLDER": "We couldn't find any replication jobs!", "JOB_LOG_VIEWER": "View Replication Job Log", "NO_ENDPOINT_INFO": "Please go to registries and add an endpoint first", - "NO_PROJECT_INFO": "Please go to projects and add a project first", + "NO_PROJECT_INFO": "Please go to projects and add a project name first", "FILTER": "Filter", "SCHEDULE": "Scheduled", "MANUAL": "Manual", @@ -327,8 +328,10 @@ "TARGETS":"Target", "MODE": "Mode", "SOURCE": "Source", + "REPLICATE": "Replicate", "DELETE_REMOTE_IMAGES":"Delete remote images when locally deleted", - "REPLICATE_IMMEDIATE":"Replicate existing images immediately" + "REPLICATE_IMMEDIATE":"Replicate existing images immediately", + "NEW": "New" }, "DESTINATION": { "NEW_ENDPOINT": "Nuevo Endpoint", diff --git a/src/ui_ng/src/i18n/lang/zh-cn-lang.json b/src/ui_ng/src/i18n/lang/zh-cn-lang.json index a2ef5c66c..f2dcfabd6 100644 --- a/src/ui_ng/src/i18n/lang/zh-cn-lang.json +++ b/src/ui_ng/src/i18n/lang/zh-cn-lang.json @@ -42,8 +42,8 @@ "DELETED_FAILURE": "删除失败", "SWITCH_SUCCESS": "切换成功", "SWITCH_FAILURE": "切换失败", - "REPLICATE_SUCCESS": "复成功", - "REPLICATE_FAILURE": "复制失败" + "REPLICATE_SUCCESS": "开始成功", + "REPLICATE_FAILURE": "开始失败" }, "TOOLTIP": { "EMAIL": "请使用正确的邮箱地址,比如name@example.com。", @@ -249,7 +249,8 @@ "DELETION_TITLE_FAILURE": "规则确认删除失败", "REPLICATION_TITLE": "复制规则确认", "REPLICATION_SUMMARY": "确认复制规则 {{param}}?", - "DELETION_SUMMARY_FAILURE": "{{param}} 有 pending/running/retrying 状态,不能删除", + "DELETION_SUMMARY_FAILURE": "有 pending/running/retrying 状态,不能删除", + "REPLICATE_SUMMARY_FAILURE": "有 pending/running 状态,不能删除", "FILTER_TARGETS_PLACEHOLDER": "过滤目标", "DELETION_TITLE_TARGET": "删除目标确认", "DELETION_SUMMARY_TARGET": "确认删除目标 {{param}}?", @@ -310,14 +311,14 @@ "TOGGLED_SUCCESS": "切换复制规则状态成功。", "CANNOT_EDIT": "当复制规则启用时无法修改。", "POLICY_ALREADY_EXISTS": "规则已存在。", - "FAILED_TO_DELETE_POLICY_ENABLED": "删除复制规则失败: 仍有未完成的任务或规则未停用。", + "FAILED_TO_DELETE_POLICY_ENABLED": "删除复制规则失败: 仍有未完成的任务。", "FOUND_ERROR_IN_JOBS": "复制任务中包含错误,请检查。", "INVALID_DATE": "无效日期。", "PLACEHOLDER": "未发现任何复制规则!", "JOB_PLACEHOLDER": "未发现任何复制任务!", "JOB_LOG_VIEWER": "查看复制任务日志", "NO_ENDPOINT_INFO": "请先添加目标", - "NO_PROJECT_INFO": "请先添加项目", + "NO_PROJECT_INFO": "请先去项目添加一个新的项目名称", "FILTER": "过滤", "SCHEDULE": "定时", "MANUAL": "手动", @@ -327,8 +328,10 @@ "TARGETS":"目标", "MODE": "模式", "SOURCE": "资源", + "REPLICATE": "复制", "DELETE_REMOTE_IMAGES":"删除本地镜像时同时也删除远程的镜像。", - "REPLICATE_IMMEDIATE":"立即复制现有的镜像。" + "REPLICATE_IMMEDIATE":"立即复制现有的镜像。", + "NEW": "新增" }, "DESTINATION": { "NEW_ENDPOINT": "新建目标",